// ==UserScript==
// @name         bro3_Auto_Bilder
// @namespace    http://at-n2.net/
// @description  ブラウザ三国志 自動建築スクリプト ronf再作成版
// @include      http://*.3gokushi.jp/*
// @version      1.0.0
// ==/UserScript==

//2010.10.25 「研究中」「建物削除中」の時建設されないバグを修正
//2010.10.28 「ALLクリア」機能実装
//2010.10.28 市場糧自動変換機能仮実装
//2010.10.29 城・砦・村がレベルアップされないバグを修正
//2010.10.29 市場糧自動変換機能バグ取り完了
//2010.10.31 糧村化機能実装
//2010.12.24 数箇所調整+放置ミス対策して勝手に本家として公開ｗ by nottisan
//           30分以上拠点画面以外であれば自動で拠点画面へ （自動出兵ツールを使ってる人が居るかもしれないことがあるので、
//           出兵選択画面・出兵寸前の画面(/facility/castle_send_troop.php)では動作しません。）
//2010.12.31 糧の変換パターンを追加
//           平均変換：糧が指定した量になると、３資源で一番少ない物を指定値変換します。
//           一括変換：糧が指定した量になると、各指定値で変換します。
//           自動内政発動機能を追加（x知識、x技術、呉の治世、王佐の才）のみスキル使用します。
//                                  拠点表示時にスキルの使用をチェックします。
//2011.01.02 自動内政発動機能にあった、スキル3つ持ちの武将でないと発動しないバグを修正
//           http://krote.blog21.fc2.com/blog-entry-54.htmlのブログを参考にchromeに対応？
//           ※テストが不十分ですが、FierFox版に問題無いので載せて公開しました。
//2011.01.05 拠点単位の設定の読み込みの不具合修正。

var WOOD = 101; //木の内部コード
var STONE = 102; //石の内部コード
var IRON = 103; //鉄の内部コード
var RICE = 104; //糧の内部コード

//グローバル変数
var VERSION = "1.0.0";  //バージョン情報
var INTERVAL=1000;  //負荷対策 回線速度によっては正常動作しない時があります。その際は数値を増やしてください。1秒=1000
var HOST = location.hostname; //アクセスURLホスト
var PGNAME = "_Auto_Bilder_plus_"; //グリモン領域への保存時のPGの名前
var d = document;

var OPT_FUC_NAME = {"拠点": 0,
										"伐採所": 1,
										"石切り場": 2,
										"製鉄所": 3,
										"畑": 4,
										"倉庫": 5,
                    "銅雀台": 6,
										"鍛冶場": 7,
										"防具工場": 8,
										"練兵所": 9,
										"兵舎": 10,
										"弓兵舎": 11,
                    "厩舎": 12,
										"宿舎": 13,
										"兵器工房": 14,
										"市場": 15,
										"訓練所": 16,
										"水車": 17,
										"工場": 18,
                    "研究所": 19,
										"大宿舎": 20,
										"遠征訓練所": 21,
										"見張り台": 22,
										"修行所": 23
};

var d = document;
var $ = function(id) { return d.getElementById(id); };
var $x = function(xp,dc) { return d.evaluate(xp, dc||d, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; };
var $a = function(xp,dc) { var r = d.evaluate(xp, dc||d, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var a=[]; for(var i=0; i<r.snapshotLength; i++){ a.push(r.snapshotItem(i)); } return a; };
var $e = function(e,t,f) { if (!e) return; e.addEventListener(t, f, false); };

//LvUPリンク
var LVUPLINK = "http://SITE/facility/build.php?x=urlX&y=urlY&village_id=viID#ptop";
var URL_SITE = "SITE";
var URL_X = "urlX";
var URL_Y = "urlY";
var URL_viID = "viID";

//新規作成リンク
var CREATELINK = "http://SITE/facility/build.php?id=fID&x=urlX&y=urlY&village_id=viID";
var URL_fID = "fID"; //建物のID
var fID_HATAKE = 215;		//畑
var fID_SUZUME = 216;		//銅雀台
var fID_ICHIBA = 217;		//市場
var fID_SOUKO = 233;		//倉庫
var fID_SYUKUSYA = 242;	//宿舎

var DELETELINK ="http://SITE/facility/facility.php";
var DELETEPARAM = "ssid=urlSSID&x=urlX&y=urlY&remove=%E5%BB%BA%E7%89%A9%E3%82%92%E5%A3%8A%E3%81%99";
var URL_SSID = "urlSSID";


///////////////////////////////////////////////
//JSONでデータ保存
//
//
(function () {
	var CLASS_TYPE = '___class___';
	var VALUE_TYPE = '___value___';
	var DEPTH = 20;
	var convert = function(value, depth) {
		var result;
		if (value instanceof Array) {
			result = [];
			for (var i = 0, l = value.length; i < l; ++i) {
				if (depth > 0) {
					result[i] = convert(value[i], depth - 1);
				}
			}
		} else if (value instanceof Date) {
			result = {};
			result[CLASS_TYPE] = 'Date';
			result[VALUE_TYPE] = value.getTime();
		} else if (value instanceof Object) {
			result = {};
			for (var i in value) {
				if (depth > 0) {
					result[i] = convert(value[i], depth - 1);
				}
			}
		} else {
			result = value;
		}
		return result;
	};
	var deconvert = function(value, depth) {
		if (depth > 0) {
			if (value instanceof Array) {
				for (var i = 0, l = value.length; i < l; ++i) {
					value[i] = deconvert(value[i], depth - 1);
				}
			} else if (value instanceof Object && CLASS_TYPE in value && VALUE_TYPE in value) {
				if (value[CLASS_TYPE] === 'Date') {
					value = new Date(value[VALUE_TYPE]);
				}
			} else if (value instanceof Object) {
				for (var i in value) {
					value[i] = deconvert(value[i], depth - 1);
				}
			}
		}
		return value;
	};
	AB_setJSONValue = function(name, value) {
		value = convert(value, DEPTH);
		var jsonValue = JSON.stringify(value);
		GM_setValue(name, jsonValue);
	};
	AB_getJSONValue = function(name, defaultValue) {
		var jsonValue = GM_getValue(name);
		if (jsonValue != undefined) {
			var value = JSON.parse(jsonValue);
			return deconvert(value, DEPTH);
		} else {
			return defaultValue;
		}
	};
})();


///////////////////////////////////////////////
//Chrome用GM_関数
// @copyright 2009, James Campos
// @license cc-by-3.0; http://creativecommons.org/licenses/by/3.0/
if ((typeof GM_getValue == 'undefined') || (GM_getValue('a', 'b') == undefined)) {
	GM_addStyle = function(css) {
		var style = document.createElement('style');
		style.textContent = css;
		document.getElementsByTagName('head')[0].appendChild(style);
	};

	GM_deleteValue = function(name) {
		localStorage.removeItem(name);
	};

	GM_getValue = function(name, defaultValue) {
		var value = localStorage.getItem(name);
		if (!value)
		return defaultValue;
		var type = value[0];
		value = value.substring(1);
			switch (type) {
				case 'b':
				return value == 'true';
				case 'n':
				return Number(value);
				default:
				return value;
			}
	};

	GM_log = function(message) {
		if (window.opera) {
			opera.postError(message);
		return;
		}
		console.log(message);
	};

	GM_registerMenuCommand = function(name, funk) {
	//todo
	};

	GM_setValue = function(name, value) {
		value = (typeof value)[0] + value;
		localStorage.setItem(name, value);
	};
}
///////////////////////////////////////////////

function cajaxRequest(url, method, param, func_success, func_fail){
	var req = new XMLHttpRequest();
	req.onreadystatechange = function() {
		if (req.readyState == 4) {
			if (req.status == 200 && func_success) {
				func_success(req);
			} else if (req.status != 200 && func_fail) {
				func_fail(req);
			}
		}
	};
	GM_log(url, method, param);
	req.open(method, url, true);
	if (method.toLowerCase() == 'post'){
		req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	}
	req.send(param);
	return true;
}

var debug = function () {
	if (unsafeWindow.console) unsafeWindow.console.log.apply(unsafeWindow.console, arguments);
};

///////////////////////////////////////////////
//
//unsafeWindow.console.log(toTree({"aaa.bbb:0": "aaa.bbb:0", "aaa.bbb:1": "aaa.bbb:1", "aaa.ccc": "aaa.ccc"}));
//unsafeWindow.console.log(toFlat({"aaa": {"bbb": ["aaa.bbb:0", "aaa.bbb:1"], "ccc": "aaa.ccc"}}));
//{
//	"aaa.bbb:0": "aaa.bbb:0",
//	"aaa.bbb:1": "aaa.bbb:1",
//	"aaa.ccc": "aaa.ccc"
//}
//{
//	"aaa": {
//		"bbb": ["aaa.bbb:0", "aaa.bbb:1"],
//		"ccc": "aaa.ccc"
//	}
//}

var toTree = function (flatData, treeData) {
	if (treeData == undefined) treeData = {};
	for (var i in flatData) {
		var currentTreeData = treeData;
		var prevPosition = 0;
		var objectPosition = i.indexOf('.', prevPosition);
		var arrayPosition = i.indexOf(':', prevPosition);
		while (true) {
			if (objectPosition >= prevPosition && (arrayPosition < 0 || objectPosition < arrayPosition)) {
				var currentKey = i.substring(prevPosition, objectPosition);
				if (currentTreeData[currentKey] == undefined) currentTreeData[currentKey] = {};
				currentTreeData = currentTreeData[currentKey];
				prevPosition = objectPosition + 1;
				objectPosition = i.indexOf('.', prevPosition);
			} else if (arrayPosition >= prevPosition) {
				var currentKey = i.substring(prevPosition, arrayPosition);
				if (currentTreeData[currentKey] == undefined) currentTreeData[currentKey] = [];
				currentTreeData = currentTreeData[currentKey];
				prevPosition = arrayPosition + 1;
				arrayPosition = i.indexOf(':', prevPosition);
			} else {
				var currentKey = i.substring(prevPosition);
				currentTreeData[currentKey] = flatData[i];
				break;
			}
		}
	}
	return treeData;
};

var toFlat = function (treeData, flatData) {
	if (flatData == undefined) flatData = {};
	var currentTreeData = treeData;
	var nextTreeData = {};
	while (true) {
		var match = false;
		for (var i in currentTreeData) {
			if (Object.prototype.toString.call(currentTreeData[i]) == "[object Array]") {
				for (var j = 0, l = currentTreeData[i].length; j < l; ++j) {
					match = true;
					nextTreeData[i + ':' + j] = currentTreeData[i][j];
				}
			} else if (Object.prototype.toString.call(currentTreeData[i]) == "[object Object]") {
				for (var j in currentTreeData[i]) {
					match = true;
					nextTreeData[i + '.' + j] = currentTreeData[i][j];
				}
			} else {
				flatData[i] = currentTreeData[i];
			}
		}
		if (!match) break;
		currentTreeData = nextTreeData;
		nextTreeData = {};
	}
	return flatData;
}


///////////////////////////////////////////////


var isMixi = true;


var Container = function () {this.initialize.apply(this, arguments);};
(function () {
	Container.mouseHoldContainer = null;
	Container.mouseHoldX = null;
	Container.mouseHoldY = null;
	Container.prototype = {
		initialize: function(popupLeft, popupTop, id) {
			var container = d.createElement("div");
			container.id = id;
			this.idPrefix = id + ":";
			container.style.position = "absolute";
			container.style.backgroundColor = "darkgray";
			container.style.border = "outset 2px darkgray";
			container.style.left = popupLeft + "px";
			container.style.top = popupTop + "px";
			container.style.fontSize = "10px";
			container.style.padding = "3px";
			container.style.zIndex = 999;
			d.body.appendChild(container);
			this.container = container;

			$e(container, "mousedown", function(event){
				if( event.target != $(container.id)) {return false;}
				Container.mouseHoldContainer = this;
				Container.mouseHoldX = event.pageX - parseInt(this.style.left,10);
				Container.mouseHoldY = event.pageY - parseInt(this.style.top,10);
				event.preventDefault();
			});

			this.tables = [];
			this.rows = [];
			this.cells = [];
			this.currentTableIndex = -1;
			this.currentRowIndex = -1;
			this.currentCellIndex = -1;
			this.onCell = false;
			this.dataIds = {};
		},
		getCurrentTarget: function() {
			if (this.onCell) {
				return this.getCurrentCell();
			} else {
				return this.container;
			}
		},
		createTitle: function(text) {
			var span = d.createElement("span");
			span.style.fontSize = "12px";
			span.innerHTML = text;
			this.getCurrentTarget().appendChild(span);
		},
		createTable: function(options) {
			options = options || {};
			var table = d.createElement("table");
			table.style.border = "0px";
			this.container.appendChild(table);
			this.tables.push(table);
			this.rows.push([]);
			this.cells.push([]);
			this.currentTableIndex = this.tables.length - 1;
			this.currentRowIndex = -1;
			this.currentCellIndex = -1;
			if (options.colnum) {
				this.colnum = options.colnum;
				for (var i = 0, l = options.colnum; i < l; ++i) {
					var cols = d.createElement("cols");
					table.appendChild(cols);
				}
			}
			if (options.style) {
				Utility.append(table.style, options.style);
			}
			this.onCell = true;
			return this;
		},
		createBlackRoundTable: function(options) {
			options = options || {};
			this.createTable(options);
			this.tables[this.currentTableIndex].style.border = "outset 2px black";
			return this;
		},
		getCurrentTable: function() {
			return this.tables[this.currentTableIndex];
		},
		createRow: function(options) {
			options = options || {};
			var tr = d.createElement("tr");
			this.tables[this.currentTableIndex].appendChild(tr);
			if (options.style) {
				Utility.append(tr.style, options.style);
			}
			this.rows[this.currentTableIndex].push(tr);
			this.cells[this.currentTableIndex].push([]);
			this.currentRowIndex = this.rows[this.currentTableIndex].length - 1;
			this.currentCellIndex = -1;
			this.onCell = true;
			return this;
		},
		getCurrentRow: function() {
			return this.rows[this.currentTableIndex][this.currentRowIndex];
		},
		createRowCell: function(options) {
			options = options || {};
			options.colspan = this.colnum || 1;
			this.createRow(options.rowOptions);
			this.createCell(options);
		},
		createCell: function(options) {
			options = options || {};
			if (this.currentRowIndex == -1) this.createRow(options.rowOptions);
			var td = d.createElement("td");
			td.style.padding = "3px";
			td.style.verticalAlign = "top";
			if (options.style) {
				Utility.append(td.style, options.style);
			}
			if (options.text != undefined) td.innerHTML = options.text;
			if (options.colspan != undefined) td.colSpan = options.colspan;
			this.rows[this.currentTableIndex][this.currentRowIndex].appendChild(td);
			this.cells[this.currentTableIndex][this.currentRowIndex].push(td);
			this.currentCellIndex = this.cells[this.currentTableIndex][this.currentRowIndex].length - 1;
			this.onCell = true;
			return this;
		},
		getCurrentCell: function() {
			return this.cells[this.currentTableIndex][this.currentRowIndex][this.currentCellIndex];
		},
		createBlackRoundRow: function(options) {
			options = options || {};
			this.createRow(options);
			this.rows[this.currentTableIndex][this.currentRowIndex].style.border = "outset 2px black";
			return this;
		},
		setCellData: function(data) {
			this.cells[this.currentTableIndex][this.currentRowIndex][this.currentCellIndex].innerHTML = data;
			return this;
		},
		createCheckBox: function(id, text, title, left) {
			return this.createInputSet(id, "checkbox", text, title, left);
		},
		createTextBox: function(id, text, title, size, left) {
			return this.createInputSet(id, "text", text, title, left, {size: size});
		},
		createSelectBox: function(id, opts, text, title, left) {
			return this.createInputSet(id, "select", text, title, left, {options: opts});
		},
		createInputSet: function(id, type, text, title, left, options) {
			options = options || {};
			if (this.onCell && this.currentCellIndex == -1) this.createCell();
			var dv = d.createElement("span");
			dv.title = title;
			var lb = d.createElement("label");
			lb.htmlFor = this.idPrefix + id;
			lb.title = title;
			var tx;
			if (text != undefined && text !== '') {
				tx = d.createTextNode(text);
			}
			var ip;
			var posBefore = false;
			if (type == "select") {
				ip = d.createElement("select");
				var opts = options.options || {};
				for (var i in opts) {
					var opt = d.createElement("option");
					opt.value = i;
					opt.appendChild(d.createTextNode(opts[i]));
					ip.appendChild(opt);
				}
				ip.id = this.idPrefix + id;
			} else {//"input"
				ip = d.createElement("input");
				ip.type = type;
				ip.id = this.idPrefix + id;
				if (type == "checkbox") {
					ip.value = 1;
					posBefore = true;
				} else if (type == "text") {
					ip.size = options.size || 0;
				}
			}

			if (posBefore) {
				lb.appendChild(ip);
				if (tx != undefined) lb.appendChild(tx);
			} else {
				if (tx != undefined) lb.appendChild(tx);
				lb.appendChild(ip);
			}
			dv.appendChild(lb);
			this.dataIds[id] = type;
			this.getCurrentTarget().appendChild(dv);
			this.addNbsp();
			return this;
		},
		addNbsp: function() {
			if (this.onCell && this.currentCellIndex == -1) this.createCell();
			var nbsp = d.createElement("span");
			nbsp.innerHTML = "&nbsp;";
			this.getCurrentTarget().appendChild(nbsp);
		},
		createButton: function(id, text, title, func) {
			if (this.onCell && this.currentCellIndex == -1) this.createCell();
			var btn = d.createElement("input");
			btn.id = this.idPrefix + id;
			btn.type = "button";
			btn.value = text;
			btn.title = title;
			this.getCurrentTarget().appendChild(btn);
			this.addNbsp();
			$e(btn, "click", func);
			return this;
		},
		createLink: function(id, text, title, func) {
			if (this.onCell && this.currentCellIndex == -1) this.createCell();
			var link = d.createElement("a");
			link.id = this.idPrefix + id;
			link.href = "javascript:void(0);";
			link.innerHTML = text;
			this.getCurrentTarget().appendChild(link);
			this.addNbsp();
			$e(link, "click", func);
			return this;
		},
		setValue: function(data) {
			var flatData = toFlat(data);
			for (var i in flatData) {
				if (i in this.dataIds) {
					var type = this.dataIds[i];
					var target = $(this.idPrefix + i);
					var value = flatData[i];
					if (type == "checkbox") {
						target.checked = !!value;
					} else if (type == "text") {
						target.value = value;
					} else if (type == "select") {
						var options = target.options;
						for (var j = 0, m = options.length; j < m; ++j) {
							var option = options[j];
							if (options.value == value) {
								options.selected = true;
								break;
							}
						}
					}
				}
			}
		},
		getValue: function() {
			var flatData = {};
			for (i in this.dataIds) {
				var type = this.dataIds[i];
				var target = $(this.idPrefix + i);
				if (type == "checkbox") {
					flatData[i] = target.checked;
				} else if (type == "text") {
					flatData[i] = target.value;
				} else if (type == "select") {
					var options = target.options;
					for (var j = 0, m = options.length; j < m; ++j) {
						var option = options[j];
						if (options.selected) {
							flatData[i] = options.value;
							break;
						}
					}
				}
			}
			return toTree(flatData);
		}
	}
	$e(d, "mousemove", function(event){
		if(Container.mouseHoldContainer == null) return true;
		var container = Container.mouseHoldContainer;
		var x = event.pageX - Container.mouseHoldX;
		var y = event.pageY - Container.mouseHoldY;
		container.style.left = x + "px";
		container.style.top = y + "px";
		csaveData("config_window_x", x);
		csaveData("config_window_y", y);
	});
	$e(d, "mouseup", function(event){Container.mouseHoldContainer = null;});
} )();

var Facility = function () {this.initialize.apply(this, arguments);};
var Village = function () {this.initialize.apply(this, arguments);};
var Game = function () {this.initialize.apply(this, arguments);};
Game.ResourceType = {
	wood: {id: 101, code: 'wood', name: '木'},
	stone: {id: 102, code: 'stone', name: '石'},
	iron: {id: 103, code: 'iron', name: '鉄'},
	rice: {id: 104, code: 'rice', name: '糧'}
};
Game.getResourceCapacity = function() {
	return parseInt($('rice_max').innerHTML, 10);
};
Game.getResources = function() {
	return {
		wood: parseInt($(Game.ResourceType.wood.code).innerHTML, 10),
		stone: parseInt($(Game.ResourceType.stone.code).innerHTML, 10),
		iron: parseInt($(Game.ResourceType.iron.code).innerHTML, 10),
		rice: parseInt($(Game.ResourceType.rice.code).innerHTML, 10)
	};
};
Game.getResourcesIncrese = function() {
	var matches = $x('//p[@class="status_bottom"]').textContent.match(/木\s+(\-?\d+)\s+\+?(\-?\d+)\s+\|\s+石\s+(\-?\d+)\s+\+?(\-?\d+)\s+\|\s+鉄\s+(\-?\d+)\s+\+?(\-?\d+)\s+\|\s+糧\s+(\-?\d+)\s+\+?(\-?\d+)/);
	return {
		wood: parseInt(matches[1], 10) + parseInt(matches[2], 10),
		stone: parseInt(matches[3], 10) + parseInt(matches[4], 10),
		iron: parseInt(matches[5], 10) + parseInt(matches[6], 10),
		rice: parseInt(matches[7], 10) + parseInt(matches[8], 10)
	};
};
Game.getResource = function(type) {
	return parseInt($(Game.ResourceType[type]).innerHTML, 10);
};
Game.getServerTime = function() {
	var time = $('server_time').innerHTML.match(/^(\d{4})-(\d{1,2})-(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/);
	return new Date(time[1], time[2] - 1, time[3], time[4], time[5], time[6]);
};
Game.getSSID = function() {
	if (Game.SSID === undefined) {
		var xpath = document.evaluate('//form[@id="queue_exec_form"]//input[@name="ssid"]/@value', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		if (xpath.snapshotLength > 0) {
			Game.SSID = xpath.snapshotItem(0).textContent;
		} else {
			Game.SSID = null;
		}
	}
	return Game.SSID;
};
Game.getCurrentVillage = function() {
	if (Game.CurrentVillage === undefined) {
		var village = new Village();
		village.parseStatuses();
		village.saveVillageInfo();
		village.clearCheckNextTimeIfExpired();
		Game.clearForceNextActionIfCurrent();
		Game.CurrentVillage = village;
	}
	return Game.CurrentVillage;
};
Game.getCurrentVillageID = function(notUseInfo) {
	if (Game.VillageID === undefined) {
		var xpath = document.evaluate('//form[@id="queue_exec_form"]//input[@name="village_id"]/@value', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		if (xpath.snapshotLength > 0) {
			Game.VillageID = xpath.snapshotItem(0).textContent;
		} else if (!notUseInfo){
			var villageInfo = Game.getVillageInfo();
			Game.VillageID = villageInfo.villageID;
		}
	}
	return Game.VillageID;
};
Game.getCurrentVillagePosition = function(notUseInfo) {
	if (Game.VillagePosition === undefined) {
		var xyElem = document.evaluate('//div[@id="basepoint"]/span[@class="xy"]',
			document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		if (xyElem.snapshotLength > 0) {
			Game.VillagePosition = trim(xyElem.snapshotItem(0).textContent);
		} else if (!notUseInfo){
			var villageInfo = Game.getVillageInfo();
			Game.VillagePosition = villageInfo.position;
		}
	}
	return Game.VillagePosition;
}
Game.getCurrentVillageName = function(notUseInfo) {
	if (Game.VillageName === undefined) {
		var xyElem = document.evaluate('//div[@id="basepoint"]/span[@class="basename"]',
			document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		if (xyElem.snapshotLength > 0) {
			Game.VillageName = trim(xyElem.snapshotItem(0).textContent);
		} else if (!notUseInfo){
			var villageInfo = Game.getVillageInfo();
			Game.VillageName = villageInfo.name;
		}
	}
	return Game.VillageName;
};
Game.getNextAction = function() {
	var nextAction;
	var villagesInfo = Game.getVillagesInfo();
	var nowTime = Game.getServerTime().getTime();
	for (var position in villagesInfo) {
		var statuses = villagesInfo[position].statuses;
		if (statuses != null) {
			if (statuses.buildStatuses != undefined) {
				for (var i = 0, l = statuses.buildStatuses.length; i < l; ++i) {
					var targetTime = statuses.buildStatuses[i].finish.getTime() - 60 * 1000;
					if (nextAction == null || targetTime < nextAction.time) {
						nextAction = {position: position, time: targetTime};
					}
				}
			}
			if (statuses.removeStatus != undefined) {
				var targetTime = statuses.removeStatus.finish.getTime() - 60 * 1000;
				if (nextAction == null || targetTime < nextAction.time) {
					nextAction = {position: position, time: targetTime};
				}
			}
			if (statuses.domesticStatus != undefined) {
				var targetTime = statuses.domesticStatus.finish.getTime() + 1000;
				if (nextAction == null || targetTime < nextAction.time) {
					nextAction = {position: position, time: targetTime};
				}
			}
		}
		var checkNextTime = villagesInfo[position].checkNextTime;
		if (checkNextTime != null) {
			var targetTime = checkNextTime.getTime();
			if (nextAction == null || targetTime < nextAction.time) {
				nextAction = {position: position, time: targetTime};
			}
		}
		if (nextAction != null && nextAction.time != null) {
			nextAction.date = new Date(nextAction.time);
		}
	}
	return nextAction;
};
Game.getNextVillageInfo = function() {
	var villagesInfo = Game.getVillagesInfo();
	for (var pos in villagesInfo) return villagesInfo[pos];
}
Game.getNextVillageInfo = function() {
	var villagesInfo = Game.getVillagesInfo();
	var currentPos = Game.getCurrentVillagePosition();
	if (currentPos == undefined) return;
	var first = null;
	var flag = false;
	var nextVillageInfo = null;
	for (var pos in villagesInfo) {
		if (first === null) first = pos;
		if (flag) {
			nextVillageInfo = villagesInfo[pos];
			break;
		}
		if (pos == currentPos) flag = true;
	}
	if (first != null && nextVillageInfo == null) nextVillageInfo = villagesInfo[first];
//	if (nextVillageInfo.position === currentPos) {
//		nextVillageInfo = null;
//	}
	return nextVillageInfo;
};
Game.getVillagesInfo = function() {
	if (Game.VillagesInfo === undefined) {
		var villagesInfo = AB_getJSONValue(HOST+PGNAME+"VillagesInfo", {});
		var currentPosition = Game.getCurrentVillagePosition(true);
		var positionsString = $a("//div[@id='lodgment']/div[@class='floatInner']//li/a/@title");
		if (currentPosition && positionsString.length > 0) {
			var existsVillagesInfo = {};
			if (currentPosition in villagesInfo) {
				existsVillagesInfo[currentPosition] = Utility.mergeRecursively(Game.DefaultVillageInfo, villagesInfo[currentPosition]);
			}
			for (var i = 0, l = positionsString.length; i < l; ++i) {
				var position = positionsString[i].textContent.replace(/^[^\(]*\(/, '(').replace(/\)[^\)]*$/, ')');
				if (position in villagesInfo) {
					existsVillagesInfo[position] = Utility.mergeRecursively(Game.DefaultVillageInfo, villagesInfo[position]);
				}
			}
			Game.VillagesInfo = existsVillagesInfo;
		} else {
			for (var i in villagesInfo) {
				villagesInfo[i] = Utility.mergeRecursively(Game.DefaultVillageInfo, villagesInfo[i]);
			}
			Game.VillagesInfo = villagesInfo;
		}
	}
	return Game.VillagesInfo;
};
Game.isExistsVillage = function(position) {
	return position in Game.getVillagesInfo();
};
Game.DefaultVillageSetting = {
	facility: {
		201: {enable: false, maxlv: 0, gradient: 1},
		209: {enable: false, maxlv: 0, gradient: 1, count: 1},
		211: {enable: false, maxlv: 0, gradient: 1, count: 1},
		213: {enable: false, maxlv: 0, gradient: 1, count: 1},
		215: {enable: false, maxlv: 0, gradient: 1, count: 1},
		216: {enable: false, maxlv: 0, gradient: 1},
		217: {enable: false, maxlv: 0, gradient: 1},
		218: {enable: false, maxlv: 0, gradient: 1},
		219: {enable: false, maxlv: 0, gradient: 1},
		220: {enable: false, maxlv: 0, gradient: 1},
		222: {enable: false, maxlv: 0, gradient: 1},
		229: {enable: false, maxlv: 0, gradient: 1},
		230: {enable: false, maxlv: 0, gradient: 1},
		231: {enable: false, maxlv: 0, gradient: 1},
		232: {enable: false, maxlv: 0, gradient: 1},
		233: {enable: false, maxlv: 0, gradient: 1, count: 1},
		234: {enable: false, maxlv: 0, gradient: 1},
		235: {enable: false, maxlv: 0, gradient: 1},
		236: {enable: false, maxlv: 0, gradient: 1},
		237: {enable: false, maxlv: 0, gradient: 1},
		241: {enable: false, maxlv: 0, gradient: 1},
		242: {enable: false, maxlv: 0, gradient: 1, count: 1},
		243: {enable: false, maxlv: 0, gradient: 1},
		244: {enable: false, maxlv: 0, gradient: 1, count: 1},
		245: {enable: false, maxlv: 0, gradient: 1},
		246: {enable: false, maxlv: 0, gradient: 1}
	},
	remove_shukusha: false,
	akichi_count: 0,
	dome: false,
	ichiba: false,
	ichiba_pa: 0,
	ichiba_rice_max: 30000,
	ichiba_to_wood: 10000,
	ichiba_to_stone: 10000,
	ichiba_to_iron: 10000,
};
Game.getVillageSetting = function(position) {
	if (position == undefined) position = Game.getCurrentVillagePosition();
	var villagesSetting = Game.getVillagesSetting();
	return villagesSetting[position] || Utility.mergeRecursively(Game.DefaultVillageSetting);
};
Game.getVillagesSetting = function() {
	if (Game.VillagesSetting === undefined) {
		villagesSetting = AB_getJSONValue(HOST+PGNAME+"VillagesSetting", {});
		for (var i in villagesSetting) {
			villagesSetting[i] = Utility.mergeRecursively(Game.DefaultVillageSetting, villagesSetting[i]);
		}
		Game.VillagesSetting = villagesSetting;
	}
	return Game.VillagesSetting;
};
Game.saveVillagesSetting = function(villagesSetting) {
	Game.VillagesSetting = villagesSetting;
	AB_setJSONValue(HOST+PGNAME+"VillagesSetting", Game.VillagesSetting);
};
Game.saveVillageSetting = function(villagePosition, villageSetting) {
	var villagesSetting = Game.getVillagesSetting();
	villagesSetting[villagePosition] = Utility.mergeRecursively(Game.DefaultVillageSetting, villageSetting);
	Game.saveVillagesSetting(villagesSetting);
};
Game.saveVillagesInfo = function(villagesInfo) {
	Game.VillagesInfo = villagesInfo;
	AB_setJSONValue(HOST+PGNAME+"VillagesInfo", Game.VillagesInfo);
};
Game.getVillageInfo = function(position) {
	if (position == undefined) position = Game.getCurrentVillagePosition();
	var villagesInfo = Game.getVillagesInfo();
	return villagesInfo[position] || Utility.mergeRecursively(Game.DefaultVillageInfo);
};
Game.DefaultVillageInfo = {
	statuses: {},
	name: null,
	position: null,
	castle: false,
	url: null,
	villageID: null,
	checkNextTime: null
};
Game.saveVillageInfoByVillage = function(info) {
	var villagesInfo = Game.getVillagesInfo();
	if (info.position in villagesInfo) {
		var statuses = Utility.merge(Game.DefaultVillageInfo.statuses, villagesInfo[info.position].statuses, info.statuses);
		villagesInfo[info.position] = Utility.merge(Game.DefaultVillageInfo, villagesInfo[info.position], info);
		villagesInfo[info.position].statuses = statuses;
	}
	Game.saveVillagesInfo(villagesInfo);
};
Game.saveVillagesInfoByProfile = function() {
	var oldVillagesInfo = Game.getVillagesInfo();
	var newVillagesInfo = {};

	var landElems = document.evaluate(
		'//*[@id="gray02Wrapper"]//table/tbody/tr',
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var isLandList = false;
	var first = true;
	for (var i=0; i<landElems.snapshotLength; i++) {
		var item = landElems.snapshotItem(i);
		var firstElem = getChildElement(item, 0);
		if (!isLandList) {
			if (trim(firstElem.innerHTML) == "名前") {
				isLandList = true;
			}
			continue;
		}
		
		//拠点じゃなければ終了
		if (!isNumeric(getChildElement(item, 2).innerHTML)) break;
		
		//名前項目を取得
		var nameElem = getChildElement(firstElem, 0);
		var url = nameElem.href;
		
		//座標項目を取得
		var xy = "(" + getChildElement(item, 1).innerHTML + ")";
		
		var newVillageInfo = {
			name: trim(nameElem.innerHTML),
			position: xy,
			castle: first,
			url: url,
			villageID: Bro3Util.getVillageIDFromUrl(url)
		};
		//データマージ
		if (xy in oldVillagesInfo) {
			newVillageInfo = Utility.merge(Game.DefaultVillageInfo, oldVillagesInfo[xy], newVillageInfo);
		} else {
			newVillageInfo = Utility.merge(Game.DefaultVillageInfo, newVillageInfo);
		}
		newVillagesInfo[newVillageInfo.position] = newVillageInfo;
		first = false;
	}
	
	//保存
	Game.saveVillagesInfo(newVillagesInfo);
};
Game.DefaultGameInfo = {
	ichibaInfo: {},
	forceNextAction: null,
	nextVillagePosition: null
};
Game.getGameInfo = function() {
	if (Game.GameInfo === undefined) {
		Game.GameInfo = Utility.merge(Game.DefaultGameInfo, AB_getJSONValue(HOST+PGNAME+"GameInfo", {}));
	}
	return Game.GameInfo;
};
Game.saveGameInfo = function(gameInfo) {
	Game.GameInfo = gameInfo;
	AB_setJSONValue(HOST+PGNAME+"GameInfo", Game.GameInfo);
};
Game.DefaultGameSetting = {
	enable: false,
	avc: false,
	ichiba: {
		min1: {enable: false, wood: 30000, wood_limit: 80000, stone: 30000, stone_limit: 80000, iron: 20000, iron_limit: 60000, rice: 10000, rice_limit: 5000},
		max1: {enable: false, maxHours: 2, minHours: 4, convertRate: {wood: 1, stone: 1, iron: 1}},
		max2: {enable: false, maxRice: 200000, convertAmount: {wood: 10000, stone: 10000, iron: 10000}, maxAmount: {wood: 200000, stone: 200000, iron: 200000}}
	},
	kifu : {enable: false, rice_max: 10000, rice: 1000}
};
Game.getGameSetting = function() {
	if (Game.GameSetting === undefined) {
		Game.GameSetting = Utility.mergeRecursively(Game.DefaultGameSetting, AB_getJSONValue(HOST+PGNAME+"GameSetting", {}));
	}
	return Game.GameSetting;
};
Game.saveGameSetting = function(gameSetting) {
	Game.GameSetting = gameSetting;
	AB_setJSONValue(HOST+PGNAME+"GameSetting", Game.GameSetting);
};
Game.enableAB = function() {
	var gameSetting = Game.getGameSetting();
	gameSetting.enable = true;
	Game.saveGameSetting(gameSetting);
};
Game.disableAB =function() {
	var gameSetting = Game.getGameSetting();
	gameSetting.enable = false;
	Game.saveGameSetting(gameSetting);
};
Game.getIchibaInfo = function() {
	var gameInfo = Game.getGameInfo();
	return gameInfo.ichibaInfo;
};
Game.saveIchibaInfoIfOver = function(newIchibaInfo) {
	var gameInfo = Game.getGameInfo();
	var ichibaInfo = gameInfo.ichibaInfo
	if (ichibaInfo.position != undefined) {
		if (!Game.isExistsVillage(ichibaInfo.position)) {
			ichibaInfo = undefined;
		}
	}
	if (ichibaInfo.lv == undefined || ichibaInfo.lv < newIchibaInfo.lv) {
		gameInfo.ichibaInfo = newIchibaInfo;
		Game.saveGameInfo(gameInfo);
	}
};
Game.getForceNextAction = function() {
	var gameInfo = Game.getGameInfo();
	return gameInfo.forceNextAction;
};
Game.saveForceNextAction = function(forceNextAction) {
	var gameInfo = Game.getGameInfo();
	gameInfo.forceNextAction = forceNextAction;
	Game.saveGameInfo(gameInfo);
};
Game.clearForceNextActionIfCurrent = function() {
	var gameInfo = Game.getGameInfo();
	if (gameInfo.forceNextAction != null && gameInfo.forceNextAction == Game.getCurrentVillagePosition()) {
		gameInfo.forceNextAction = null;
		Game.saveGameInfo(gameInfo);
	}
}
Facility.ichiba = [0.4,0.42,0.44,0.46,0.48,0.5,0.52,0.54,0.56,0.6];
Facility.Type = {
	100: {
		'id': 100,
		'name': '平地',
		'buildable': true,
		'lvupable': false,
		'deletable': false,
		'notOnlyOne': true
	},
	101: {
		'id': 101,
		'name': '森林',
		'buildable': false,
		'lvupable': false,
		'deletable': false,
		'notOnlyOne': true
	},
	102: {
		'id': 102,
		'name': '岩山',
		'buildable': false,
		'lvupable': false,
		'deletable': false,
		'notOnlyOne': true
	},
	103: {
		'id': 103,
		'name': '鉄鉱山',
		'buildable': false,
		'lvupable': false,
		'deletable': false,
		'notOnlyOne': true
	},
	104: {
		'id': 104,
		'name': '穀物',
		'buildable': false,
		'lvupable': false,
		'deletable': false,
		'notOnlyOne': true
	},
	106: {
		'id': 106,
		'name': '荒地',
		'buildable': false,
		'lvupable': false,
		'deletable': false,
		'notOnlyOne': true
	},
	201: {
		'id': 201,
		'name': '拠点',
	},
	205: {
		'id': 205,
		'name': '城',
		'maxlv': 20,
		'cost': [
			[0, 0, 0, 0],
			[1404, 546, 390, 780],
			[2570, 1000, 714, 1428],
			[4161, 2081, 2081, 2081],
			[7102, 3552, 3552, 3552],
			[9056, 9056, 6037, 6037],
			[14384, 14384, 9589, 9589],
			[22773, 22773, 15183, 15183],
			[33562, 33562, 22374, 22374],
			[44402, 57559, 32890, 29602],
			[65122, 84418, 48239, 43415],
			[95317, 123558, 70605, 63544],
			[113458, 154716, 154716, 92830],
			[150418, 150418, 315878, 135375],
			[219008, 219008, 492770, 164258],
			[294820, 294820, 663345, 221115],
			[488220, 488220, 827854, 318406],
			[839130, 839130, 915414, 457707],
			[1307581, 1307581, 1354280, 700491],
			[1901938, 1901938, 1969864, 1018896]
		],
		'settingID': 201
	},
	209: {
		'id': 209,
		'name': '伐採所',
		'maxlv': 15,
		'cost': [
			[10,35,40,15],
			[25, 88, 100, 38],
			[58, 202, 230, 86],
			[173, 604, 690, 259],
			[431, 1510, 1725, 647],
			[1466, 2847, 3019, 1294],
			[2493, 4839, 5132, 2200],
			[3490, 6775, 7186, 3080],
			[4537, 8807, 9341, 4003],
			[5898, 11450, 12144, 5204],
			[8119, 14434, 15787, 6766],
			[11366, 20207, 22101, 9472],
			[17050, 30311, 33152, 14208],
			[25575, 45467, 49729, 21312],
			[38362, 68199, 74593, 31698]
		],
		'notOnlyOne': true,
		'adjoining' : 101
	},
	211: {
		'id': 211,
		'name': '石切り場',
		'maxlv': 15,
		'cost': [
			[40, 10, 35, 15],
			[100, 25, 88, 38],
			[230, 58, 202, 86],
			[690, 173, 604, 259],
			[1725, 431, 1510, 647],
			[3019, 1466, 2847, 1294],
			[5132, 2493, 4839, 2200],
			[7186, 3490, 6775, 3080],
			[9341, 4537, 8807, 4003],
			[12144, 5898, 11450, 5204],
			[15787, 8119, 14434, 6766],
			[22101, 11366, 20207, 9472],
			[33152, 17050, 30311, 14208],
			[49729, 25575, 45467, 21312],
			[74593, 38362, 68199, 31968]
		],
		'notOnlyOne': true,
		'adjoining' : 102
	},
	213: {
		'id': 213,
		'name': '製鉄所',
		'maxlv': 15,
		'cost': [
			[35, 40, 10, 15],
			[88, 100, 25, 38],
			[202, 230, 58, 86],
			[604, 690, 173, 259],
			[1510, 1725, 431, 647],
			[2847, 3019, 1466, 1294],
			[4839, 5132, 2493, 2200],
			[6775, 7186, 3490, 3080],
			[8807, 9341, 4537, 4003],
			[11450, 12144, 5898, 5204],
			[14434, 15787, 8119, 6766],
			[20207, 22101, 11366, 9472],
			[30311, 33152, 17050, 14208],
			[45467, 49729, 25575, 21312],
			[68199, 74593, 38362, 31968]
		],
		'notOnlyOne': true,
		'adjoining' : 103
	},
	215: {
		'id': 215,
		'name': '畑',
		'maxlv': 15,
		'cost': [
			[35, 35, 30, 0],
			[88, 88, 75, 0],
			[202, 202, 173, 0],
			[604, 604, 518, 0],
			[1510, 1510, 1294, 0],
			[3019, 3019, 2588, 0],
			[5132, 5132, 4399, 0],
			[7186, 7186, 6159, 0],
			[9341, 9341, 8007, 0],
			[12144, 12144, 10409, 0],
			[15787, 15787, 13532, 0],
			[22101, 22101, 18944, 0],
			[33152, 33152, 28416, 0],
			[49729, 49729, 42625, 0],
			[74593, 74593, 63937, 0]
		],
		'notOnlyOne': true
	},
	216: {
		'id': 216,
		'name': '銅雀台',
		'maxlv': 10,
		'cost': [
			[700, 3500, 2100, 700],
			[1120, 5600, 3360, 1120],
			[1792, 8960, 5376, 1792],
			[3763, 10035, 7526, 3763],
			[5263, 14049, 10537, 5268],
			[9834, 14752, 14752, 9834],
			[13768, 20652, 20652, 13768],
			[17899, 26848, 26848, 17899],
			[23268, 34902, 34902, 23268],
			[30249, 45373, 45373, 30249]
		],
		'dependencies': [
			{'id': 215, 'lv': 5}
		]
	},
	217: {
		'id': 217,
		'name': '市場',
		'maxlv': 10,
		'cost': [
			[100, 100, 50, 50],
			[334, 334, 191, 191],
			[1035, 1035, 592, 592],
			[2795, 2795, 1600, 1600],
			[6328, 6328, 4218, 4218],
			[13288, 13288, 8859, 8859],
			[25248, 25248, 16832, 16832],
			[42921, 42921, 28614, 28614],
			[64381, 64381, 42921, 42921],
			[90134, 90134, 60089, 60089]
		],
		'dependencies': [
			{'id': 231, 'lv': 2}
		]
	},
	218: {
		'id': 218,
		'name': '水車',
		'maxlv': 10,
		'cost': [
			[2940, 980, 980, 4900],
			[4704, 1568, 1568, 7840],
			[7526, 2509, 2509, 12544],
			[10537, 5268, 5268, 14049],
			[14751, 7376, 7376, 19668],
			[20652, 13768, 13768, 20652],
			[28913, 19275, 19275, 28913],
			[37587, 25058, 25058, 37587],
			[48863, 32576, 32576, 48863],
			[63523, 42348, 42348, 63523]
		],
		'dependencies': [
			{'id': 217, 'lv': 8},
			{'id': 233, 'lv': 10},
			{'id': 234, 'lv': 5}
		]
	},
	219: {
		'id': 219,
		'name': '工場',
		'maxlv': 10,
		'cost': [
			[780, 1560, 1560, 3900],
			[1248, 2496, 2496, 6240],
			[1997, 3994, 3994, 9984],
			[4193, 6290, 6290, 11182],
			[5871, 8806, 8806, 15655],
			[10958, 13698, 13698, 16437],
			[15342, 19177, 19177, 23013],
			[19944, 24930, 24930, 29916],
			[25928, 32410, 32410, 38891],
			[33706, 42132, 42132, 50559]
		],
		'dependencies': [
			{'id': 217, 'lv': 10},
			{'id': 241, 'lv': 5}
		]
	},
	220: {
		'id': 220,
		'name': '村',
		'maxlv': 15,
		'cost': [
			[400, 136, 104, 160],
			[936, 319, 243, 374],
			[1685, 573, 438, 673],
			[2467, 1357, 1110, 1233],
			[4194, 2307, 1887, 2097],
			[7191, 3954, 3236, 3596],
			[11505, 6327, 5177, 5753],
			[18776, 13560, 10430, 9387],
			[33912, 24492, 18839, 16956],
			[61043, 44087, 33914, 30523],
			[106495, 85196, 66939, 45640],
			[190570, 152456, 119786, 81672],
			[340166, 272133, 213820, 145786],
			[505021, 456148, 423566, 244365],
			[844765, 763014, 708513, 408756]
		],
		'settingID': 201
	},
	222: {
		'id': 220,
		'name': '砦',
		'maxlv': 15,
		'cost': [
			[104, 400, 136, 160],
			[243, 936, 319, 374],
			[438, 1685, 573, 673],
			[1110, 2467, 1357, 1233],
			[1887, 4194, 2307, 2097],
			[3236, 7191, 3954, 3596],
			[5177, 11505, 6327, 5753],
			[10430, 18776, 13560, 9387],
			[18839, 33912, 24492, 16956],
			[33914, 61043, 44087, 30523],
			[66939, 106495, 85196, 45640],
			[119786, 190570, 152456, 81672],
			[213820, 340166, 272133, 145786],
			[423566, 505021, 456148, 244365],
			[708513, 844765, 763014, 408756]
		],
		'settingID': 201
	},
	229: {
		'id': 229,
		'name': '訓練所',
		'maxlv': 10,
		'cost': [
			[1500, 1600, 2500, 3300],
			[2100, 2240, 3500, 3300],
			[2940, 3136, 4900, 6468],
			[6629, 7326, 13955, 6978],
			[13257, 14653, 27910, 13955],
			[32097, 37679, 55821, 13955],
			[64194, 75358, 111642, 27910],
			[128388, 150716, 223283, 55821],
			[256776, 301432, 446566, 111642],
			[513551, 602865, 893133, 223283]
		],
		'dependencies': [
			{'id': 216, 'lv': 7},
			{'id': 232, 'lv': 5}
		]
	},
	230: {
		'id': 230,
		'name': '研究所',
		'maxlv': 10,
		'cost': [
			[275, 110, 110, 55],
			[413, 165, 165, 83],
			[619, 248, 248, 124],
			[1486, 836, 836, 557],
			[2228, 1253, 1253, 836],
			[7521, 6267, 6267, 5015],
			[13538, 11282, 11282, 9025],
			[21436, 17862, 17862, 14290],
			[44675, 37228, 37228, 29784],
			[87725, 73104, 73104, 58483]
		],
		'dependencies': [
			{'id': 209, 'lv': 3},
			{'id': 211, 'lv': 2}
		]
	},
	231: {
		'id': 231,
		'name': '防具工場',
		'maxlv': 10,
		'cost': [
			[150, 200, 340, 170],
			[300, 400, 680, 340],
			[585, 780, 1326, 663],
			[1112, 1482, 2519, 1260],
			[2056, 2742, 4661, 2330],
			[3701, 4935, 8390, 4195],
			[6477, 8636, 14682, 7341],
			[14112, 17640, 28223, 10584],
			[25253, 31566, 50506, 18940],
			[40404, 50506, 80809, 30303]
		],
		'dependencies': [
			{'id': 234, 'lv': 3},
			{'id': 242, 'lv': 1}
		]
	},
	232: {
		'id': 232,
		'name': '鍛冶場',
		'maxlv': 10,
		'cost': [
			[150, 200, 340, 170],
			[400, 300, 680, 340],
			[780, 585, 1326, 663],
			[1482, 1112, 2519, 1260],
			[2742, 2056, 4661, 2330],
			[4935, 3701, 8390, 4195],
			[8636, 6477, 14682, 7341],
			[17640, 14112, 28223, 10584],
			[31566, 25253, 50506, 18940],
			[50506, 40404, 80809, 30303]
		],
		'dependencies': [
			{'id': 234, 'lv': 3}
		]
	},
	233: {
		'id': 233,
		'name': '倉庫',
		'maxlv': 20,
		'cost': [
			[83, 141, 83, 63],
			[167, 281, 167, 126],
			[300, 506, 300, 226],
			[479, 810, 479, 362],
			[671, 1134, 671, 507],
			[1044, 1253, 1044, 835],
			[1462, 1754, 1462, 1169],
			[1973, 2368, 1973, 1578],
			[2664, 3196, 2664, 2131],
			[3596, 4315, 3596, 2877],
			[4854, 5825, 4854, 3883],
			[6311, 7573, 6311, 5048],
			[8204, 9845, 8204, 6563],
			[10255, 12306, 10255, 8204],
			[12819, 15382, 12819, 10255],
			[15382, 18459, 15382, 12306],
			[18459, 22151, 18459, 14767],
			[21228, 21228, 25473, 16982],
			[24412, 29294, 24412, 19529],
			[28074, 33688, 28074, 22459]
		],
		'notOnlyOne': true
	},
	234: {
		'id': 234,
		'name': '練兵所',
		'maxlv': 10,
		'cost': [
			[112, 107, 107, 122],
			[224, 214, 214, 244],
			[448, 428, 428, 488],
			[759, 725, 725, 826],
			[1214, 1160, 1160, 1322],
			[2209, 2110, 2110, 2406],
			[3331, 3182, 3182, 3627],
			[4958, 4736, 4736, 5400],
			[8091, 7729, 7729, 8813],
			[11130, 10632, 10632, 12122]
		],
		'dependencies': [
			{'id': 233, 'lv': 1}
		]
	},
	235: {
		'id': 235,
		'name': '兵舎',
		'maxlv': 15,
		'cost': [
			[72, 360, 72, 216],
			[144, 720, 144, 432],
			[288, 1440, 288, 864],
			[648, 1728, 648, 1296],
			[972, 2592, 972, 1944],
			[1409, 3758, 1409, 2819],
			[2725, 4088, 2725, 4088],
			[6744, 9810, 5518, 2453],
			[12140, 17658, 9933, 4415],
			[21852, 31784, 17879, 7946],
			[39333, 57212, 32182, 14303],
			[70800, 96545, 64364, 25745],
			[127440, 173781, 115854, 46342],
			[254879, 324392, 254879, 92683],
			[509759, 648784, 509759, 185367]
		],
		'dependencies': [
			{'id': 242, 'lv': 3}
		]
	},
	236: {
		'id': 236,
		'name': '弓兵舎',
		'maxlv': 15,
		'cost': [
			[360, 72, 72, 216],
			[720, 144, 144, 432],
			[1440, 288, 288, 864],
			[1728, 648, 648, 1296],
			[2592, 972, 972, 1944],
			[3758, 1409, 1409, 2819],
			[5450, 2044, 2044, 4087],
			[9810, 6131, 6131, 2453],
			[17658, 12140, 9933, 4415],
			[31784, 21852, 17879, 7946],
			[57212, 39333, 32182, 14303],
			[96545, 70800, 64364, 25745],
			[173781, 127440, 115854, 46342],
			[324392, 254879, 254879, 92683],
			[648784, 509759, 509759, 185367]
		],
		'dependencies': [
			{'id': 231, 'lv': 1},
			{'id': 242, 'lv': 3}
		]
	},
	237: {
		'id': 237,
		'name': '厩舎',
		'maxlv': 15,
		'cost': [
			[72, 72, 360, 216],
			[144, 144, 720, 432],
			[288, 288, 1440, 864],
			[648, 648, 1728, 1296],
			[972, 972, 2592, 1944],
			[1409, 1409, 3758, 2891],
			[2044, 2044, 5450, 4087],
			[5518, 6744, 9810, 2453],
			[9933, 12140, 17658, 4415],
			[17879, 21852, 31784, 7946],
			[32182, 39333, 57212, 14303],
			[64364, 70800, 96545, 25745],
			[115854, 127440, 173781, 46342],
			[254879, 254879, 324392, 92683],
			[509759, 509759, 648784, 185367]
		],
		'dependencies': [
			{'id': 232, 'lv': 1},
			{'id': 242, 'lv': 5}
		]
	},
	241: {
		'id': 241,
		'name': '兵器工房',
		'maxlv': 15,
		'cost': [
			[216, 216, 216, 72],
			[432, 432, 432, 144],
			[864, 864, 864, 288],
			[1224, 1224, 1224, 648],
			[1836, 1836, 1836, 972],
			[2662, 2662, 2662, 1409],
			[3860, 3860, 3860, 2044],
			[7357, 7357, 7357, 2452],
			[13242, 13242, 13242, 4414],
			[23836, 23836, 23836, 7945],
			[42905, 42905, 42905, 14302],
			[77229, 77229, 77229, 25743],
			[139013, 139013, 139013, 46338],
			[278026, 278026, 278026, 92675],
			[556051, 556051, 556051, 185350]
		],
		'dependencies': [
			{'id': 231, 'lv': 3},
			{'id': 232, 'lv': 3}
		]
	},
	242: {
		'id': 242,
		'name': '宿舎',
		'maxlv': 15,
		'cost': [
			[35, 20, 35, 80],
			[53, 30, 53, 120],
			[89, 51, 89, 204],
			[147, 84, 147, 337],
			[228, 130, 228, 522],
			[336, 192, 336, 767],
			[476, 272, 476, 1089],
			[653, 373, 653, 1492],
			[868, 496, 868, 1984],
			[1129, 645, 1129, 2580],
			[2032, 1161, 2032, 4644],
			[3658, 2090, 3658, 4644],
			[6951, 3971, 6950, 15882],
			[13205, 7544, 13205, 30177],
			[25090, 14334, 25090, 57336]
		],
		'dependencies': [
			{'id': 234, 'lv': 1}
		],
		'notOnlyOne': true
	},
	243: {
		'id': 243,
		'name': '見張り台',
		'maxlv': 15,
		'cost': [
			[600, 840, 600, 360 ],
			[960, 1344, 960, 576],
			[1536, 2150, 1536, 922],
			[2458, 3441, 2458, 1475],
			[3932, 5505, 3932, 2359],
			[6291, 8808, 6291, 3775],
			[9437, 13212, 9437, 5662],
			[14156, 19818, 14156, 8493],
			[21233, 29727, 21233, 12740],
			[31850, 44590, 31850, 19110],
			[44590, 62426, 44590, 26754],
			[62426, 87396, 62426, 37456],
			[87397, 122355, 87397, 52438],
			[122355, 171297, 122355, 73413],
			[159062, 222686, 159062, 95437],
			[206780, 289492, 206780, 124068]
		],
		'dependencies': [
			{'id': 231, 'lv': 7}
		]
	},
	244: {
		'id': 244,
		'name': '大宿舎',
		'maxlv': 20,
		'cost': [
			[200, 114, 200, 438],
			[320, 183, 320, 701],
			[512, 293, 512, 1121],
			[768, 439, 768, 1682],
			[1152, 658, 1152, 2523],
			[1728, 987, 1728, 3784],
			[2419, 1382, 2419, 5298],
			[3387, 1935, 3387, 7418],
			[4741, 2709, 4741, 10385],
			[6637, 3793, 6637, 14538],
			[8628, 4930, 8628, 18900],
			[11217, 6409, 11217, 24570],
			[14582, 8332, 14582, 31941],
			[18956, 11735, 18956, 40620],
			[25817, 16429, 25817, 49286],
			[32271, 22003, 32271, 60141],
			[42172, 29337, 42172, 69675],
			[52715, 38963, 52715, 84803],
			[66009, 49506, 66009, 93512],
			[79211, 62708, 79211, 108914]
		],
		'dependencies': [
			{'id': 242, 'lv': 15},
			{'id': 243, 'lv': 8}
		],
		'notOnlyOne': true
	},
	245: {
		'id': 245,
		'name': '修行所',
		'maxlv': 20,
		'cost': [
			[1600, 1200, 600, 600],
			[2240, 1680, 840, 840],
			[3136, 2352, 1176, 1176],
			[4390, 3293, 1646, 1646],
			[6146, 4610, 2305, 2305],
			[8605, 6454, 3227, 3227],
			[11186, 8390, 4195, 4195],
			[14542, 10907, 5453, 5453],
			[18905, 14179, 7089, 7089],
			[24577, 18433, 9216, 9216],
			[31950, 23963, 11981, 11981],
			[38340, 28755, 14378, 14378],
			[46008, 34506, 17253, 17253],
			[55210, 41407, 20704, 20704],
			[66252, 49689, 24844, 24844],
			[72877, 54658, 27329, 27329],
			[80164, 60123, 30062, 30062],
			[88181, 66136, 33068, 33068],
			[96999, 72749, 36375, 36375],
			[106699, 80024, 40012, 40012]
		],
		'dependencies': [
			{'id': 205, 'lv': 8}
		]
	},
	246: {
		'id': 246,
		'name': '遠征訓練所',
		'maxlv': 15,
		'cost': [
			[2884, 4486, 5977, 2723],
			[4614, 7177, 9484, 4357],
			[7382, 11483, 15174, 6972],
			[11811, 18373, 24279, 11155],
			[18898, 29397, 38846, 17848],
			[28347, 44096, 58269, 26772],
			[42521, 66143, 87404, 40158],
			[63781, 99215, 131105, 60238],
			[89294, 138901, 183548, 84333],
			[125011, 194461, 256967, 118066],
			[175015, 272246, 359754, 165292],
			[227520, 353920, 467680, 214880],
			[295776, 460096, 607984, 279344]
		],
		'dependencies': [
			{'id': 229, 'lv': 5},
			{'id': 244, 'lv': 8}
		]
	},
};

Facility.NameType = {
	'平地': 100,
	'森林': 101,
	'岩山': 102,
	'鉄鉱山': 103,
	'穀物': 104,
	'荒地': 106,
	'拠点': 201,
	'城': 205,
	'伐採所': 209,
	'石切り場': 211,
	'製鉄所': 213,
	'畑': 215,
	'銅雀台': 216,
	'市場': 217,
	'水車': 218,
	'工場': 219,
	'村': 220,
	'砦': 222,
	'訓練所': 229,
	'研究所': 230,
	'防具工場': 231,
	'鍛冶場': 232,
	'倉庫': 233,
	'練兵所': 234,
	'兵舎': 235,
	'弓兵舎': 236,
	'厩舎': 237,
	'兵器工房': 241,
	'宿舎': 242,
	'見張り台': 243,
	'大宿舎': 244,
	'修行所': 245,
	'遠征訓練所': 246
};
Facility.checkResources = function (id_or_name, lv) {
	var id = Facility.getIdByIdOrName(id_or_name);
	var costs = Facility.Type[id].cost || [];
	if (lv == null) {
		lv = 0;
	}
	if (costs != undefined && costs[lv]) {
		var resources = Game.getResources();
		var cost = costs[lv];
		if (cost[0] < resources.wood
				&& cost[1] < resources.stone
				&& cost[2] < resources.iron
				&& cost[3] < resources.rice) {
			return true;
		}
	}
	return false;
};
Facility.getIdByIdOrName = function(id_or_name) {
	var id;
	if (isNaN(id_or_name)) {
		id = Facility.NameType[id_or_name];
	} else {
		id = id_or_name;
	}
	return id;
};
Facility.prototype = {
	initialize: function(x, y, id_or_name, lv) {
		this.x = parseInt(x, 10);
		this.y = parseInt(y, 10);
		this.lv = parseInt(lv, 10);
		if (isNaN(id_or_name)) {
			this.id = Facility.NameType[id_or_name];
		} else {
			this.id = parseInt(id_or_name);
		}
		this.settingID = Facility.Type[this.id].settingID || this.id;
	},
	isEnoughResourceForLevelup: function() {
		return Facility.checkResources(this.id, this.lv);
	},
	levelup: function() {
		var maxlv = Facility.Type[this.id].maxlv || 0;
		if (maxlv > this.lv && this.isEnoughResourceForLevelup() && this.buildStatus == null) {
			var mURL = LVUPLINK.replace(URL_SITE, HOST)
					.replace(URL_X, this.x)
					.replace(URL_Y, this.y)
					.replace(URL_viID, Game.getCurrentVillageID());
			GM_log(mURL);
			setTimeout(function() {location.href = mURL;}, INTERVAL);
			return true;
		}
		return false;
	},
	remove: function() {
		if (this.lv > 0 && this.buildStatus == null) {
			var url = DELETELINK.replace(URL_SITE, HOST);
			var param = DELETEPARAM.replace(URL_SSID, Game.getSSID())
					.replace(URL_X, this.x)
					.replace(URL_Y, this.y);
			cajaxRequest(url, "POST", param, function () {
				setTimeout(function() {location.reload();}, INTERVAL);
			});
			return true;
		}
		return false;
	},
	isUnderConstruction: function() {
		return this.buildStatus != null && this.buildStatus.status == '建設中';
	},
	isUnderDemolition: function() {
		return this.buildStatus != null && this.buildStatus.status == '削除中';
	},
	isInPreparation: function() {
		return this.buildStatus != null && this.buildStatus.status == '建設準備中';
	},
	isUnderConstructionOrInPreparation: function() {
		return this.buildStatus != null && (this.buildStatus.status == '建設中' || this.buildStatus.status == '建設準備中');
	},
	hasAdjoining: function(type) {
		if (type === 101) {
			return this.adjoining[101] > 0;
		} else if (type === 102) {
			return this.adjoining[102] > 0;
		} else if (type === 103) {
			return this.adjoining[103] > 0;
		} else if (type === 104) {
			return this.adjoining[104] > 0;
		} else {
			return this.adjoining[101] + this.adjoining[102] + this.adjoining[103] + this.adjoining[104] > 0;
		}
	},
	getAdjoiningRankImportant: function(type) {
		if (type === 101) {
			return this.adjoining[101] + this.adjoining[102] * 4 + this.adjoining[103] * 4 + this.adjoining[104] * 2;
		} else if (type === 102) {
			return this.adjoining[101] * 4 + this.adjoining[102] + this.adjoining[103] * 4 + this.adjoining[104] * 2;
		} else if (type === 103) {
			return this.adjoining[101] * 4 + this.adjoining[102] * 4 + this.adjoining[103] + this.adjoining[104] * 2;
		} else if (type === 104) {
			return this.adjoining[101] * 4 + this.adjoining[102] * 4 + this.adjoining[103] * 4 + this.adjoining[104];
		} else {
			return this.adjoining[101] * 4 + this.adjoining[102] * 4 + this.adjoining[103] * 4 + this.adjoining[104] * 2;
		}
	}
}
Village.MAX_FACILITY_AREA_X = 6;
Village.MAX_FACILITY_AREA_Y = 6;
Village.prototype = {
	initialize: function() {
		this.isStatusesParsed = false;
		this.buildStatuses = [];
		this.removeStatus = null;
		this.weaponSmithStatus = null;
		this.guardSmithStatus = null;
		this.researchStatus = null;
		this.domesticStatus = null;
	},
	convertResources: function(actions) {
		var ichiba = this.getFirstFacility(217);
		if (ichiba) {
			var innerAction = function (actions) {
				if (actions.length > 0) {
					var action = actions.shift();
					var data = "form2=&x=" + ichiba.x + "&y=" + ichiba.y + "&change_btn=" + encodeURIComponent("はい") + "&st=1&tf_id=" + action.from + "&tc=" + action.amount + "&tt_id=" + action.to;
					var tid=setTimeout(function(){
						console.log("http://" + HOST + "/facility/facility.php");
						GM_xmlhttpRequest({
							method:"POST", 
							url:"http://" + HOST + "/facility/facility.php",
							headers:{"Content-type":"application/x-www-form-urlencoded"},
							data: data,
							onload:function(x){
								if (actions.length > 0) {
									innerAction(actions);
								} else {
									var tid=setTimeout(function(){location.reload();}, INTERVAL);
								}
							}
						});
					},INTERVAL);
				}
			};
			innerAction(actions);
		}
	},
	parseStatuses: function() {	
		var actionElems = document.evaluate('//*[@id="actionLog"]/ul/li', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		var buildRegexp = /(建設中|建設準備中)\s*([^\s]*)\(レベル(\d+)\)が(\d{2}:\d{2}:\d{2})に完了します。\(あと(\d{2,3}:\d{2}:\d{2})\)/;
		var removeRegexp = /([^\s]*)\(レベル(\d+)\)を(削除中)です。(\d{2}:\d{2}:\d{2})に完了します。\(あと(\d{2,3}:\d{2}:\d{2})\)/;
		var smithRegexp = /^(.*)の(武器|防具)を強化しています/;
		var researchRegexp = /研究中です/;
		var buildStatuses = [];
		var removeStatus = null;
		var domesticStatus = null;
		for (var i = 0, l = actionElems.snapshotLength; i < l; ++i) {
			var actionElem = actionElems.snapshotItem(i);
			var actionText = actionElem.textContent;
			var matches;
			if (matches = actionText.match(buildRegexp)) {
				var buildStatusElem = document.evaluate('./span[@class="buildStatus"]/a', actionElem, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
				var xy = Bro3Util.getXYFromUrl(buildStatusElem.href);
				var buildStatus = {'status': matches[1], 'name': matches[2], 'lv': matches[3], 'finish': Utility.estimateDate(matches[4], matches[5], Game.getServerTime()), 'x': xy.x, 'y': xy.y};
				buildStatuses.push(buildStatus);
			} else if (matches = actionText.match(removeRegexp)) {
				var buildStatusElem = document.evaluate('./span[@class="buildStatus"]/a', actionElem, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
				var xy = Bro3Util.getXYFromUrl(buildStatusElem.href);
				removeStatus = {'status': matches[3], 'name': matches[1], 'lv': matches[2], 'finish': Utility.estimateDate(matches[4], matches[5], Game.getServerTime()), 'x': xy.x, 'y': xy.y};
			} else if (matches = actionText.match(smithRegexp)) {
			} else if (matches = actionText.match(researchRegexp)) {
			}
		}

		var domesticText = document.evaluate('//div[@id="basepoint"]/div[@class="base-skill"]/span/a', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0).textContent;
		var domesticRegexp = /^\s+(--|[^\s:]+:)\s+(--|([^\(]+)LV(\d+))\((?:<span [^>]+>)?(--:--:--|\d{2}:\d{2}:\d{2})(?:<\/span>)?\)\s+/;
		if (matches = domesticText.match(domesticRegexp)) {
			if (matches[1] !== '--') {
				if (matches[2] !== '--') {
					domesticStatus = {'status': '内政中(スキル利用中)', 'name': matches[2], 'lv': matches[3], 'finish': Utility.addTime(Game.getServerTime(), matches[4])};
				} else {
					domesticStatus = {'status': '内政中', 'name': null, 'lv': null, 'finish': null};
				}
			}
		}
		this.buildStatuses = buildStatuses;
		this.removeStatus = removeStatus;
		this.weaponSmithStatus = null;
		this.guardSmithStatus = null;
		this.researchStatus = null;
		this.domesticStatus = domesticStatus;
		this.isStatusesParsed = true;
	},
	isUnderConstruction: function() {
		if (!this.isStatusesParsed) {
			parseStatuses();
		}
		return this.buildStatuses.length > 0;
	},
	isUnderDemolition: function() {
		if (!this.isStatusesParsed) {
			parseStatuses();
		}
		return this.removeStatus != null;
	},
	isUseDomesticSkill: function() {
		if (this.domesticStatus != null && this.domesticStatus.status === '内政中(スキル利用中)') {
			return true;
		}
		return false;
	},
	isSettingDomesticPerson: function() {
		if (this.domesticStatus != null) {
			return true;
		}
		return false;
	},
	getBuildStatuses: function() {
		if (!this.isStatusesParsed) {
			parseStatuses();
		}
		return this.buildStatuses;
	},
	getStatuses: function() {
		if (!this.isStatusesParsed) {
			parseStatuses();
		}
		return {
			'buildStatuses': this.buildStatuses,
			'removeStatus': this.removeStatus
		};
	},
	getVillageInfo: function() {
		return Game.getVillageInfo();
	},
	saveVillageInfo: function() {
		Game.saveVillageInfoByVillage({
			statuses: this.getStatuses(),
			name: Game.getCurrentVillageName(),
			position: Game.getCurrentVillagePosition()
		});
	},
	parseFacilities: function() {
		var results = document.evaluate('//area', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		var facilities = new Array();
		var facilitiesIndexByXY = {};
		var altRegexp = /^([^ ]+)(?:\sLV\.(\d+))?$/;
		var ichibaLv;
		var tempAdjoining = {};
		for(var i = 0, l = results.snapshotLength; i < l; ++i){
			var item = results.snapshotItem(i);
			var matches = item.alt.match(altRegexp);
			var xy = Bro3Util.getXYFromArea(item);
			if (matches && xy) {
				var facility = new Facility(xy.x, xy.y, matches[1], matches[2]);
				facilities.push(facility);
				facilitiesIndexByXY[xy.xy] = facilities.length - 1;
				if (facility.id == 205 || facility.id == 220 || facility.id == 222) {
					this.central = facility.id;
				}
				if (xy.xy in tempAdjoining) {
					facility.adjoining = tempAdjoining[xy.xy];
					delete tempAdjoining[xy.xy];
				} else {
					facility.adjoining = {101: 0, 102: 0, 103: 0, 104: 0};
				}
				if (facility.id === 217) ichibaLv = facility.lv;
				if (facility.id === 101 || facility.id === 102 || facility.id === 103 || facility.id === 104) {
					for (var xs = -1; xs <= 1; xs = xs + 2) {
						if (xy.x + xs >= 0 && xy.x + xs <= Village.MAX_FACILITY_AREA_X) {
							var targetxy = (xy.x + xs) + ',' + xy.y;
							if (targetxy in facilitiesIndexByXY) {
								++facilities[facilitiesIndexByXY[targetxy]].adjoining[facility.id];
							} else {
								if (!(targetxy in tempAdjoining)) tempAdjoining[targetxy] = {101: 0, 102: 0, 103: 0, 104: 0};
								++tempAdjoining[targetxy][facility.id];
							}
						}
					}
					for (var ys = -1; ys <= 1; ys = ys + 2) {
						if (xy.y + ys >= 0 && xy.y + ys <= Village.MAX_FACILITY_AREA_Y) {
							var targetxy = xy.x + ',' + (xy.y + ys);
							if (targetxy in facilitiesIndexByXY) {
								++facilities[facilitiesIndexByXY[targetxy]].adjoining[facility.id];
							} else {
								if (!(targetxy in tempAdjoining)) tempAdjoining[targetxy] = {101: 0, 102: 0, 103: 0, 104: 0};
								++tempAdjoining[targetxy][facility.id];
							}
						}
					}
					++facility.adjoining[facility.id];
				}
			}
		}
		this.facilities = facilities;
		this.facilitiesIndexByXY = facilitiesIndexByXY;
		
		if (ichibaLv != undefined) {
			Game.saveIchibaInfoIfOver({position: Game.getCurrentVillagePosition(), lv: ichibaLv});
		}
		if (!this.isStatusesParsed) {
			parseStatuses();
		}
		if (this.buildStatuses.length > 0) {
			for (var i = 0, l = this.buildStatuses.length; i < l; ++i) {
				var buildStatus = this.buildStatuses[i];
				var facility = this.facilities[this.facilitiesIndexByXY[Bro3Util.joinXY(buildStatus.x, buildStatus.y)]];
				facility.buildStatus = buildStatus;
			}
		}
		if (this.removeStatus) {
			var removeStatus = this.removeStatus;
			var facility = this.facilities[this.facilitiesIndexByXY[Bro3Util.joinXY(removeStatus.x, removeStatus.y)]];
			facility.buildStatus = removeStatus;
		}
	},
	getFacility: function(x, y) {
		var facilities = this.getFacilities();
		return facilities[this.facilitiesIndexByXY[Bro3Util.joinXY(x, y)]];
	},
	getFacilities: function() {
		if (this.facilities == undefined) {
			this.parseFacilities();
		}
		return this.facilities;
	},
	getFacilitiesByVillageFacilitySetting: function(villageFacilitySetting) {
		var result = new Array();
		var facilities = this.getFacilities();
		var plural = {};
		for (i in facilities) {
			var facility = facilities[i];
			if (facility.lv == undefined) continue;
			var setting = villageFacilitySetting[facility.settingID];
			if (setting != undefined && setting.enable) {
				var settingMaxlv = parseInt(setting.maxlv, 10);
				if (setting.count != undefined) {
					if (plural[facility.settingID] == undefined) {
						plural[facility.settingID] = [];
					}
					plural[facility.settingID].push(facility);
				} else if (settingMaxlv > facility.lv) {
					result.push(facility);
				}
			}
		}
		for (i in plural) {
			var setting = villageFacilitySetting[i];
			var settingCount = parseInt(setting.count, 10);
			var settingMaxlv = parseInt(setting.maxlv, 10);
			if (settingCount > 0 && plural[i].length > settingCount) {
				plural[i].sort(function(a, b) {
					return b.lv - a.lv;
				});
				for (var j = 0, m = settingCount; j < m; ++j) {
					if (settingMaxlv > plural[i][j].lv) result.push(plural[i][j]);
				}
			} else {
				for (var j = 0, m = plural[i].length; j < m; ++j) {
					if (settingMaxlv > plural[i][j].lv) result.push(plural[i][j]);
				}
			}
		}
		result.sort(function(a, b) {
			var as = villageFacilitySetting[a.settingID];
			var bs = villageFacilitySetting[b.settingID];
			if (as.gradient == 0) {
				if (bs.gradient == 0) return 0
				return -1;
			} else if (bs.gradient == 0) return -1;
			return (a.lv / as.gradient) - (b.lv / bs.gradient);
		});
		return result;
	},
	countHeichi: function() {
		return this.countFacility(100);
	},
	countFacility: function(id_or_name) {
		var id = Facility.getIdByIdOrName(id_or_name);
		var result = 0;
		var facilities = this.getFacilities();
		for (var i = 0, l = facilities.length; i < l; ++i) {
			if (facilities[i].id == id) {
				++result;
			}
		}
		return result;
	},
	getMaxLevelFacility: function(id_or_name) {
		var id = Facility.getIdByIdOrName(id_or_name);
		var result;
		var facilities = this.getFacilities();
		for (var i = 0, l = facilities.length; i < l; ++i) {
			var facility = facilities[i];
			if (facility.id == id && (result == null || result.lv - facility.lv < 0)) {
				result = facility;
			}
		}
		return result;
	},
	isExistsFacility: function(id_or_name) {
		var id = Facility.getIdByIdOrName(id_or_name);
		var result = 0;
		var facilities = this.getFacilities();
		for (var i = 0, l = facilities.length; i < l; ++i) {
			var facility = facilities[i];
			if (facility.id == id && facility.lv != undefined) {
				return true;
			}
		}
		return false;
	},
	needBuildForTarget: function(id_or_name) {
		var id = Facility.getIdByIdOrName(id_or_name);
		var needs = [];
		var buildables = {};
		this._needBuildForTarget(id, buildables, needs);
		return {needs: needs, buildables: buildables};
	},
	needBuildForTargets: function(ids_or_names) {
		var needs = [];
		var buildables = {};
		for (var i = 0, l = ids_or_names.length; i < l; ++i) {
			var id = Facility.getIdByIdOrName(ids_or_names[i]);
			this._needBuildForTarget(id, buildables, needs);
		}
		return {needs: needs, buildables: buildables};
	},
	needBuildForTargetsExpectSelf: function(ids_or_names) {
		var ids = [];
		for (var i = 0, l = ids_or_names.length; i < l; ++i) {
			ids.push(Facility.getIdByIdOrName(ids_or_names[i]));
		}
		var result = this.needBuildForTargets(ids);
		for (var i = 0, l = ids.length; i < l; ++i) {
			if (ids[i] in result.buildables) {
				delete result.buildables[ids[i]];
			}
		}
		return result;
	},
	_needBuildForTarget: function(id, buildables, needs) {
		var targetFacility = Facility.Type[id];
		var dependencies = targetFacility.dependencies || [];
		if (!(id in buildables)) {
			var isBuildable = true;
			for (var i = 0, l = dependencies.length; i < l; ++i) {
				var dependency = dependencies[i];
				if (needs.indexOf(dependency.id) < 0) {
					var maxLevelFacility = this.getMaxLevelFacility(dependency.id);
					if (maxLevelFacility == null) {
						this._needBuildForTarget(dependency.id, buildables, needs);
						isBuildable = false;
					} else if (maxLevelFacility.lv < dependency.lv) {
						needs.push(dependency.id);
						buildables[dependency.id] = maxLevelFacility;
						isBuildable = false;
					}
				} else if (!buildables[dependency.id] || buildables[dependency.id].lv < dependency.lv) {
					isBuildable = false;
				}
			}
			needs.push(id);
			if (isBuildable) {
				buildables[id] = null;
			}
		}
		return needs.length == 0;
	},
	getFirstHeichOrderedImportant: function(id_or_name) {
		var id = Facility.getIdByIdOrName(id_or_name);
		var adjoining = Facility.Type[id].adjoining;
		var facilities = this.getFacilities();
		var minRank;
		var minRankFacility;
		for (var i = 0, l = facilities.length; i < l; ++i) {
			var facility = facilities[i];
			if (facility.id == 100) {
				if (adjoining == undefined && !facility.hasAdjoining()) {
					return facility;
				} else if (adjoining == undefined || facility.hasAdjoining(adjoining)){
					var rank = facility.getAdjoiningRankImportant(adjoining);
					if (minRank == null || rank < minRank) {
						minRank = rank;
						minRankFacility = facility;
					}
				}
			}
		}
		if (minRankFacility != undefined) {
			return minRankFacility;
		}
		return null;
	},
	getMinLevelFacilityNotAction: function(id_or_name) {
		var id = Facility.getIdByIdOrName(id_or_name);
		var facilities = this.getFacilities();
		var result;
		for (var i = 0, l = facilities.length; i < l; ++i) {
			var facility = facilities[i];
			if (facility.id == id && facility.buildStatus == null && (result == null || result.lv - facility.lv > 0)) {
				result = facility;
			}
		}
		return result;
	},
	getFirstFacility: function(id_or_name) {
		var id = Facility.getIdByIdOrName(id_or_name);
		var facilities = this.getFacilities();
		var result;
		for (var i = 0, l = facilities.length; i < l; ++i) {
			var facility = facilities[i];
			if (facility.id == id) {
				result = facility;
				break;
			}
		}
		return result;
	},
	createFacility: function(id_or_name) {
		var id = Facility.getIdByIdOrName(id_or_name);
		var heichi = this.getFirstHeichOrderedImportant(id);
		if (heichi && Facility.checkResources(id)) {
			var mURL = CREATELINK.replace(URL_SITE, HOST)
					.replace(URL_X, heichi.x)
					.replace(URL_Y, heichi.y)
					.replace(URL_viID, Game.getCurrentVillageID())
					.replace(URL_fID, id);
			GM_log(mURL);
			setTimeout(function() {location.href = mURL;}, INTERVAL);
			return true;
		}
		return false;
	},
	levelupFirstFacility: function(id_or_name) {
		var firstFacility = this.getMinLevelFacilityNotActionAnd(id_or_name);
		if (firstFacility) {
			return firstFacility.levelup();
		}
		return false;
	},
	levelupFacility: function(facility) {
		return facility.levelup();
	},
	removeFacility: function(facility) {
		return facility.remove();
	},
	levelupOrCreateByFacilityMaps: function(facilityMaps, villageFacilitySetting) {
		var createFacilityIDs = [];
		var levelupFacilities = [];
		for (var id in facilityMaps) {
			var facility = facilityMaps[id];
			if (facility != null) {
				levelupFacilities.push(facility);
			} else {
				createFacilityIDs.push(id);
			}
		}
		createFacilityIDs.sort(function(a, b) {
			return villageFacilitySetting[b].gradient - villageFacilitySetting[a].gradient;
		});
		for (var i = 0, l = createFacilityIDs.length; i < l; ++i) {
			if (this.createFacility(createFacilityIDs[i])) return true;
		}
		levelupFacilities.sort(function(a, b) {
			var as = villageFacilitySetting[a.settingID];
			var bs = villageFacilitySetting[b.settingID];
			if (as.gradient == 0) {
				if (bs.gradient == 0) return 0
				return -1;
			} else if (bs.gradient == 0) return -1;
			return (a.lv / as.gradient) - (b.lv / bs.gradient);
		});
		for (var i = 0, l = levelupFacilities.length; i < l; ++i) {
			if (levelupFacilities[i].levelup()) return true;
		}
		return false;
	},
	saveCheckNextTime: function(checkNextTime) {
		var villageInfo = this.getVillageInfo();
		if (villageInfo.checkNextTime == null || villageInfo.checkNextTime.getTime() > checkNextTime.getTime()) {
			Game.saveVillageInfoByVillage({position: villageInfo.position, checkNextTime: checkNextTime});
		}
	},
	clearCheckNextTimeIfExpired: function() {
		var villageInfo = this.getVillageInfo();
		if (villageInfo.checkNextTime != null && villageInfo.checkNextTime.getTime() < Game.getServerTime().getTime()) {
			Game.saveVillageInfoByVillage({position: villageInfo.position, checkNextTime: null});
		}
	}
};

var Bro3Util = {
	getXYFromUrl: function (url){
		if (url == "") return null;
		var matches = url.match(/[\?&]x=([\d-])+\&y=([\d-])+/);
		if (matches) {
			return {x: matches[1], y: matches[2], xy: matches[1] + ',' + matches[2]};
		}
		return null;
	},
	getXYFromArea: function(area){
		if (area.href) {
			return Bro3Util.getXYFromUrl(area.href);
		} else {
			var matches = area.getAttribute("onmouseover").match(/overOperation\('rollover', '([-\d]+)px', '([-\d]+)px'\);/);
			var x = (2 * (parseInt(matches[2], 10) + 1) + (parseInt(matches[1], 10) + 1) - 300) / 100;
			var y = (2 * (parseInt(matches[2], 10) + 1) - (parseInt(matches[1], 10) + 1) + 300) / 100;
			return {x: x, y: y, xy: x + ',' + y};
		}
	},
	getVillageIDFromUrl: function (url){
		if (url == "") return null;
		var matches = url.match(/[\?&]village_id=([\d-]+)/);
		if (matches) {
			return matches[1];
		}
		return null;
	},
	joinXY: function (x, y) {
		return x + ',' + y;
	},
	splitXY: function (xy) {
		var temp = xy.split(',');
		return temp.length >= 2? {x: temp[0], y: temp[1]}: null;
	}
};

var Utility = {
	merge: function() {
		var result = {};
		for (var i = 0, l = arguments.length; i < l; ++i) {
			var source = arguments[i];
			for (var property in source) {
				if (source.hasOwnProperty(property)) {
					result[property] = source[property];
				}
			}
		}
		return result;
	},
	mergeRecursively: function() {
		var result = {};
		for (var i = 0, l = arguments.length; i < l; ++i) {
			var source = arguments[i];
			for (var property in source) {
				if (source.hasOwnProperty(property)) {
					if (source[property] instanceof Array) {
						result[property] = Utility.mergeArrayRecursively(result[property] || [], source[property]);
					} else if (source[property] instanceof Object && source[property].constructor == Object) {
						result[property] = Utility.mergeRecursively(result[property] || {}, source[property]);
					} else {
						result[property] = source[property];
					}
				}
			}
		}
		return result;
	},
	mergeArray: function() {
		var result = [];
		for (var i = 0, l = arguments.length; i < l; ++i) {
			var source = arguments[i];
			for (var j = 0, m = source.length; j < m; ++j) {
				result[j] = source[j];
			}
		}
		return result;
	},
	mergeArrayRecursively: function() {
		var result = [];
		for (var i = 0, l = arguments.length; i < l; ++i) {
			var source = arguments[i];
			for (var j = 0, m = source.length; j < m; ++j) {
				if (source[j] instanceof Array) {
					result[j] = Utility.mergeArrayRecursively(result[j] || [], source[j]);
				} else if (source[j] instanceof Object && source[j].constructor == Object) {
					result[j] = Utility.mergeRecursively(result[j] || {}, source[j]);
				} else {
					result[j] = source[j];
				}
			}
		}
		return result;
	},
	append: function() {
		var result = arguments[0];
		for (var i = 1, l = arguments.length; i < l; ++i) {
			var source = arguments[i];
			for (var property in source) {
				if (source.hasOwnProperty(property)) {
					result[property] = source[property];
				}
			}
		}
		return result;
	},
	countProperty: function(target) {
		var count = 0;
		for(var key in target) ++count;
		return count;
	},
	toMillisecondInterval: function(interval) {
		var parts = interval.split(":");
		if (parts.length === 3) {
			return ((parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10)) * 60 + parseInt(parts[2], 10)) * 1000;
		}
		return false;
	},
	addTime: function(date, interval) {
		return new Date(date.getTime() + Utility.toMillisecondInterval(interval));
	},
	estimateDate: function(time, interval, baseDate) {
		if (baseDate == undefined) {
			baseDate = new Date();
			baseDate.setMilliseconds(0);
		}
		var times = time.split(":");
		if (times.length === 3) {
			times[0] = parseInt(times[0], 10);
			var fixDate = Utility.addTime(baseDate, interval);
			var quickFixDateHours = fixDate.getHours();
			if (quickFixDateHours !== time[0]) {
				if (times[0] === 0 && quickFixDateHours === 23) {
					fixDate.setTime(fixDate.getTime() + 24 * 60 * 60 * 1000);
				} else if (times[0] === 23 && quickFixDateHours === 0) {
					fixDate.setTime(fixDate.getTime() - 24 * 60 * 60 * 1000);
				}
				fixDate.setHours(times[0]);
			}
			fixDate.setMinutes(parseInt(times[1], 10));
			fixDate.setSeconds(parseInt(times[2], 10));
			return fixDate;
		}
		return false;
	}
};

//Main
(function(){
	var gameSetting = Game.getGameSetting();

	addOpenLinkHtml();

	//君主プロフィール画面なら都市画面URLを取得
	if ((location.pathname == "/user/" || location.pathname == "/user/index.php") &&
		getParameter("user_id") == "") {
		Game.saveVillagesInfoByProfile()
	}
	
	if (gameSetting.enable) {
		//拠点画面なら対象建築物の建築チェック
		if (location.pathname == "/village.php") {
	GM_log("setVillageFacility start");
			if (setVillageFacility()) {
				GM_log("setVillageFacility exit");
				return;
			}
	GM_log("setVillageFacility end");
			//市場処理
			if (ichibaChange()) {
				GM_log("ichibaChange exit");
				return;
			}

			//自動寄付処理
			autoDonate();

			//自動内政処理 by nottisan
			Auto_Domestic();

	GM_log("forwardNextVillage start");
			forwardNextVillage();
	GM_log("forwardNextVillage end");
		}else{
			if(location.pathname != "/facility/castle_send_troop.php"){
				forwardNextVillage();
			}
		}
	}

})();

function setVillageFacility() {
	var vID = "";
	//座標を取得
	var xyElem = document.evaluate('//*[@id="basepoint"]/span[@class="xy"]',
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	vId = trim(xyElem.snapshotItem(0).innerHTML);
	//alert(vId);
	
	//建設情報を取得
	var actionsElem = document.evaluate('//*[@id="actionLog"]/ul/li',
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

	var villageSetting = Game.getVillageSetting();
	var village = Game.getCurrentVillage();
	village.getFacilities();

	var notEnough = false;
	var notEnoughTarget = {};
	if (!village.isUnderConstruction()) {
		var countHeichi = village.countHeichi();
		var villageSettingAkichiCount = parseInt(villageSetting.akichi_count, 10);
		if (countHeichi > villageSettingAkichiCount) {
			var checkTargets = [];
			var checkPluralTargets = [];
			var checkPluralTargetsCount = {};
			for (var i in villageSetting.facility) {
				var facilitySetting = villageSetting.facility[i];
				if (facilitySetting.enable) {
					var facilityId = (i == 201? village.central: i);
					if (facilitySetting.count != undefined) {
						var facilitySettingCount = parseInt(facilitySetting.count);
						var countFacility = village.countFacility(facilityId);
						if (countFacility == 0) {
							checkTargets.push(facilityId);
						} else if (facilitySettingCount == 0 || facilitySettingCount > countFacility) {
							checkPluralTargetsCount[facilityId] = facilitySettingCount - countFacility;
							checkPluralTargets.push(facilityId);
						}
					} else {
						if (!village.isExistsFacility(facilityId)) {
							checkTargets.push(facilityId);
						}
					}
				}
			}
			var result = village.needBuildForTargets(checkTargets);
			if (village.levelupOrCreateByFacilityMaps(result.buildables, villageSetting.facility)) return;
			if (countHeichi > villageSettingAkichiCount + result.needs.length) {
				var resultPlural = village.needBuildForTargetsExpectSelf(checkPluralTargets);
				if (village.levelupOrCreateByFacilityMaps(resultPlural.buildables, villageSetting.facility)) return;
				for (var i = 0, l = checkPluralTargets.length; i < l; ++i) {
					if (checkPluralTargetsCount[checkPluralTargets[i]] > 0) {
						if (village.createFacility(checkPluralTargets[i])) return;
						notEnough = true;
						notEnoughTarget[checkPluralTargets[i]] = null;
					}
				}
				for (var i = 0, l = checkPluralTargets.length; i < l; ++i) {
					if (checkPluralTargetsCount[checkPluralTargets[i]] < 0) {
						if (village.createFacility(checkPluralTargets[i])) return;
						notEnough = true;
						notEnoughTarget[checkPluralTargets[i]] = null;
					}
				}
			}
		}

		var facilities = village.getFacilitiesByVillageFacilitySetting(villageSetting.facility);
		for (var i = 0, l = facilities.length; i < l; ++i) {
			if (facilities[i].levelup()) return;
			notEnough = true;
			notEnoughTarget[facilities[i].id] = facilities[i];
		}
	}
	if (!village.isUnderDemolition() && villageSetting.remove_shukusha) {
		var f = village.getMinLevelFacilityNotAction(242);
		if (f && f.remove()) return;
	}
	if (notEnough) {
		village.saveCheckNextTime(new Date(Game.getServerTime().getTime() + (25 * 60 + 2) * 1000));
	}
}

// 次拠点移動
function forwardNextVillage(){
	var gameSetting = Game.getGameSetting();
	var villageInfo = null;
	var interval = null;

	var forceNextAction = Game.getForceNextAction();
	if (forceNextAction != null) {
		villageInfo = Game.getVillageInfo(forceNextAction);
		interval = 0;
	}
	if(villageInfo == null && gameSetting.avc){
		var gameInfo = Game.getGameInfo();
		if (villageInfo == null || villageInfo.url == null) {
			var nextAction = Game.getNextAction();
			if (nextAction != null) {
				villageInfo = Game.getVillageInfo(nextAction.position);
				interval = nextAction.time - Game.getServerTime().getTime();
				if (interval < 32 * 1000) interval = 32 * 1000; //30秒より短い移動は30秒にする。
			}
			if (villageInfo == null || villageInfo.url == null || interval > (20 * 60 + 2) * 1000) {
				if (gameInfo.nextVillagePosition != null) {
					villageInfo = Game.getVillageInfo(gameInfo.nextVillagePosition);
					gameInfo.nextVillagePosition = null;
					Game.saveGameInfo(gameInfo);
				} else {
					villageInfo = Game.getNextVillageInfo();
				}
				if (villageInfo != null) {
					interval = (15 * 60 + 2) * 1000;
				}
			} else {
				var nextVillageInfo = Game.getNextVillageInfo();
				if (nextVillageInfo != undefined) {
					gameInfo.nextVillagePosition = nextVillageInfo.position;
					Game.saveGameInfo(gameInfo);
				}
			}
		}
	}
	if (villageInfo != null && villageInfo.url != null) {
		$('Auto_Bilder_Status').innerHTML = villageInfo.name + ": " + (new Date(Game.getServerTime().getTime() + interval)).toString();
		var tid = setTimeout(function() {location.href = villageInfo.url}, interval);
		return;
	}
	
}

//リンクHTML追加
function addOpenLinkHtml() {
	var gameSetting = Game.getGameSetting();

	var sidebar = d.evaluate('//*[@id="status"]', d, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	if (sidebar.snapshotLength == 0) return;
//	if (sidebar.snapshotLength == 0){
//		sidebar = d.evaluate('//*[@id="navi01"]',d, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
//		sidebar = d.evaluate('//*[@id="sidebar"]',d, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
//		sidebar = d.evaluate('//*[@id="status_left"]',d, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
//			if (sidebar.snapshotLength == 0) return;
//		isMixi = false;
		
//	}
	
	//自動移動リンク
	var div = d.createElement("div");
	div.id = "Auto_Bilder_Div";
	sidebar.snapshotItem(0).appendChild(div);
	var openLink = d.createElement("a");
	openLink.id = "Auto_Bilder";
	openLink.href = "javascript:void(0);";
	openLink.innerHTML = "AutoBilder";
	openLink.style.color = "#FFFFFF";
	openLink.addEventListener("click", function() {
		closeIniBilderBox();
		addIniBilderHtml();
	}, true);
	div.appendChild(openLink);
	var statusDiv = d.createElement("div");
	statusDiv.id = "Auto_Bilder_Status";
	div.appendChild(statusDiv);
}

//建築設定画面を閉じる
function closeIniBilderBox() {
	deleteIniBilderHtml();
	deleteInifacHtml();
}
//建築対象拠点表示HTML削除
function deleteIniBilderHtml() {
	var elem = d.getElementById("ABContainer");
	if (elem == undefined) return;
	d.body.removeChild(d.getElementById("ABContainer"));
}

///LvUP対象施設設定画面を閉じる
function closeInifacBox() {
	deleteInifacHtml();
}

///LvUP対象施設設のチェックボックスをクリアする
function clearInifacBox() {
	var checkbox = $a('//input[@type="checkbox"]');
	for(var i= 0;i < checkbox.length; i++) {
		checkbox[i].checked = false;
	}
}

//建築対象施設表示HTML削除
function deleteInifacHtml() {
	var elem = d.getElementById("ABfacContainer");
	if (elem == undefined) return;
	d.body.removeChild(d.getElementById("ABfacContainer"));
}

//ステイタス取得HTML追加
function addIniBilderHtml() {

//	var popupLeft = 30;
//	var popupTop = 150;

	var popupLeft = 500;
	var popupTop = 250;

	if(!isMixi) 
	{
		popupLeft = 700;
		popupTop = 200;
	}

	//表示コンテナ作成
	var container = new Container(popupLeft, popupTop, "ABContainer");

	container.createTable();
	container.createRow();
	container.createCell();

	//バージョン
	var version = d.createElement("span");
	container.createTitle("Ver." + VERSION);

	container.createRow();
	container.createCell();
	container.createCheckBox("enable", "ABを利用する","ABを動かすときチェックしてください。",0);

	var gameSetting = Game.getGameSetting();
	
	//拠点設定リンクの作成
	container.createTable();

	var villagesInfo = Game.getVillagesInfo();
	if (Utility.countProperty(villagesInfo) > 0) {
		for (var i in villagesInfo) {
			var villageInfo = villagesInfo[i];
			container.createBlackRoundRow();
			container.createCell();
			container.createLink("villageLink" + villageInfo.villageID, villageInfo.name, villageInfo.name + "の設定画面を開きます", (function() {
				var villagePos = villageInfo.position;
				return function() {
					closeInifacBox();
					addInifacHtml(villagePos);
				};
			})());
		}
	} else {
		container.createBlackRoundRow();
		container.createCell({text: "インストールありがとうございます。<br />" + 
						"まずは、プロフィール画面を開いて<br />" +
						"拠点情報を取得してください。"});
	}

	container.createTable();

	container.createRow();
	container.createCell();
	container.createCheckBox("avc", "拠点巡回","拠点を巡回する場合はチェックをしてください。",0);

	container.createBlackRoundTable({colnum: 1});
	container.createRow();
	container.createCell();
	container.createCheckBox("ichiba.min1.enable", "自動市場変換(最低量変換)","市場で変換を行う場合はチェックをしてください",0);

	container.createRow();
	container.createCell();
	container.createTextBox("ichiba.min1.wood", "木最低1", "木がこの量以下の場合、糧からの変換を考える", 7, 5);
	container.createTextBox("ichiba.min1.stone", "石最低1", "石がこの量以下の場合、糧からの変換を考える", 7, 5);
	container.createTextBox("ichiba.min1.iron", "鉄最低1", "鉄がこの量以下の場合、糧からの変換を考える", 7, 5);
	container.createTextBox("ichiba.min1.rice", "糧最低1", "糧がこの量以上の場合、他の資源に振り返ることを考える", 7, 5);
	container.createRow();
	container.createCell();
	container.createTextBox("ichiba.min1.wood_limit", "木限度1", "木がこの量迄は、可能なら振り返る", 7, 5);
	container.createTextBox("ichiba.min1.stone_limit", "石限度1", "石がこの量迄は、可能なら振り返る", 7, 5);
	container.createTextBox("ichiba.min1.iron_limit", "鉄限度1", "鉄がこの量迄は、可能なら振り返る", 7, 5);
	container.createTextBox("ichiba.min1.rice_limit", "糧限度1", "糧がこの量迄は、他の資源に振り返ることが可能", 7, 5);

	container.createBlackRoundTable({colnum: 1});
	container.createRow();
	container.createCell();
	container.createCheckBox("ichiba.max1.enable", "自動市場変換(最大量変換:時間型)","市場で変換を行う場合はチェックをしてください",0);
	container.createTextBox("ichiba.max1.maxHours", "最大＠倉庫時間", "糧の倉庫満杯までの時間がこの時間を割ったら、糧からの変換を考える", 3, 5);
	container.createTextBox("ichiba.max1.minHours", "変換限度＠倉庫時間", "糧の倉庫満杯までの時間がこの時間になるまで、糧からの変換を考える", 3, 5);
	container.createRow();
	container.createCell();
	container.createTextBox("ichiba.max1.convertRate.wood", "木変換レート", "糧のうち木への変換比率", 7, 5);
	container.createTextBox("ichiba.max1.convertRate.stone", "石変換レート", "糧のうち石への変換比率", 7, 5);
	container.createTextBox("ichiba.max1.convertRate.iron", "鉄変換レート", "糧のうち鉄への変換比率", 7, 5);

	container.createBlackRoundTable({colnum: 1});
	container.createRow();
	container.createCell();
	container.createCheckBox("ichiba.max2.enable", "自動市場変換(最大量変換:パラメータ型)","市場で変換を行う場合はチェックをしてください",0);
	container.createRow();
	container.createCell();
	container.createTextBox("ichiba.max2.convertAmount.wood", "木へ変換する糧の量", "木へ変換する糧の量", 7, 5);
	container.createTextBox("ichiba.max2.convertAmount.stone", "石へ変換する糧の量", "石へ変換する糧の量", 7, 5);
	container.createTextBox("ichiba.max2.convertAmount.iron", "鉄へ変換する糧の量", "鉄へ変換する糧の量", 7, 5);
	container.createTextBox("ichiba.max2.maxRice", "糧限度", "糧がここまで増えたら", 7, 5);
	container.createRow();
	container.createCell();
	container.createTextBox("ichiba.max2.maxAmount.wood", "木限度", "木へ変換する最大木", 7, 5);
	container.createTextBox("ichiba.max2.maxAmount.stone", "石限度", "石へ変換する最大石", 7, 5);
	container.createTextBox("ichiba.max2.maxAmount.iron", "鉄限度", "鉄へ変換する最大鉄", 7, 5);

	container.createTable();
	container.createRow();
	container.createCell();

	//自動寄付用
	container.createCheckBox("kifu", "自動寄付", "この都市に来たら、自動的に寄付します。", 0);
	container.createRow();
	container.createCell();
	container.createTextBox("kifu.rice_max", "糧が右の数量になったら寄付する","自動で糧を寄付し始める量指定します。", 7, 5);
	container.createTextBox("kifu.rice", "自動で糧を寄付する量","自動で糧を寄付する量指定します。", 7, 5);

	
	container.setValue(gameSetting);

	container.createTable();
	container.createCell();

	container.createButton("saveFacility", "保存", "設定内容を保存します", function() {
		var gameSetting = container.getValue();
		Game.saveGameSetting(gameSetting);
		var tid=setTimeout(function(){location.reload();},INTERVAL);
	});
	container.createButton("closeFacility", "閉じる", "ウインドウを閉じます", function() {
		closeIniBilderBox()
	});
}

//ステイタス取得HTML追加
function addInifacHtml(vId) {
//	var popupLeft = 128;
//	var popupTop = 150;

	var popupLeft = 230;
	var popupTop = 250;

	if(!isMixi) 
	{
		popupLeft = 430;
		popupTop = 200;
	}
	
	//表示コンテナ作成
	var container = new Container(popupLeft, popupTop, "ABfacContainer");

	//入力項目の作成
	var villageInfo = Game.getVillageInfo(vId);
	container.createTitle(villageInfo.name);

	container.createBlackRoundTable({colnum: 6});

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.201.enable", "拠点","中央の城・村・砦のLvを上げます。",0);
	container.createCell();
	container.createTextBox("facility.201.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.201.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility.233.enable", "倉庫","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.233.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.233.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);
	container.createTextBox("facility.233.count", "個数","作成、LVアップする個数、この数以上の建物がある場合、低いLVの建物は無視されます。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.209.enable", "伐採所","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.209.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.209.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);
	container.createTextBox("facility.209.count", "個数","作成、LVアップする個数、この数以上の建物がある場合、低いLVの建物は無視されます。",1);

	container.createCell();
	container.createCheckBox("facility.211.enable", "石切り場","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.211.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.211.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);
	container.createTextBox("facility.211.count", "個数","作成、LVアップする個数、この数以上の建物がある場合、低いLVの建物は無視されます。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.213.enable", "製鉄所","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.213.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.213.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);
	container.createTextBox("facility.213.count", "個数","作成、LVアップする個数、この数以上の建物がある場合、低いLVの建物は無視されます。",1);

	container.createCell();
	container.createCheckBox("facility.215.enable", "畑","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.215.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.215.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);
	container.createTextBox("facility.215.count", "個数","作成、LVアップする個数、この数以上の建物がある場合、低いLVの建物は無視されます。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.216.enable", "銅雀台","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.216.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.216.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility.217.enable", "市場","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.217.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.217.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.218.enable", "水車","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.218.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.218.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility.219.enable", "工場","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.219.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.219.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.230.enable", "研究所","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.230.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.230.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility.245.enable", "修行所","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.245.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.245.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.242.enable", "宿舎","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.242.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.242.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);
	container.createTextBox("facility.242.count", "個数","作成、LVアップする個数、この数以上の建物がある場合、低いLVの建物は無視されます。",1);

	container.createCell();
	container.createCheckBox("facility.244.enable", "大宿舎","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.244.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.244.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);
	container.createTextBox("facility.244.count", "個数","作成、LVアップする個数、この数以上の建物がある場合、低いLVの建物は無視されます。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.232.enable", "鍛冶場","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.232.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.232.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility:231.enable", "防具工場","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.231.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.231.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.234.enable", "練兵所","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.234.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.234.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility.235.enable", "兵舎","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.235.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.235.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.236.enable", "弓兵舎","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.236.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.236.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility.237.enable", "厩舎","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.237.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.237.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.241.enable", "兵器工房","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.241.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.241.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility.243.enable", "見張り台","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.243.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.243.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createRow();
	container.createCell();
	container.createCheckBox("facility.229.enable", "訓練所","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.229.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.229.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createCell();
	container.createCheckBox("facility.246.enable", "遠征訓練所","自動でLv上げをする建築物にチェックをしてください。",0);
	container.createCell();
	container.createTextBox("facility.246.maxlv", "最大LV","このLVまでLVアップをします。",1);
	container.createTextBox("facility.246.gradient", "傾き","優先度。大きいほど優先的にLV上げします。",1);

	container.createRow();
	container.createCell();
	container.createTextBox("akichi_count", "平地のまま","空けておく平地数を入力してください",1);
	container.createCell();
	container.createCheckBox("remove_shukusha", "宿舎破棄","BP増産モード用。",0);
	container.createCell();
	container.createCell();
	
	container.createTable();
	container.createCell();

	//自動内政用
	container.createCheckBox("dome", "自動内政", "この都市に来たら、自動的に内政スキルを発動します。", 0);

	container.createTable();
	container.createRow();
	container.createCell();

	//市場変換処理用
	container.createCheckBox("ichiba", "市場自動変換", "この都市で糧の市場自動変換をします。", 0);
	container.createRow();
	container.createCell();
	container.createSelectBox("ichiba_pa" , {0:"平均変換", 1:"一括変換"}, "変換パターン","平均変換：糧が一定量になった際に変換指定している一番少ない資源を変換します。   一括変換：糧が一定量になった際に指定してある資源を指定値変換します。",5);
	container.createTextBox("ichiba_rice_max", "糧が右の数量になったら変換する","自動で糧を他の資源に変換し始める量指定します。", 7, 5);
	container.createRow();
	container.createCell();
	container.createTextBox("ichiba_to_wood", "木に変換する糧の量","自動で木に変換する糧の量を指定します。", 7, 5);
	container.createTextBox("ichiba_to_stone", "石に変換する糧の量","自動で石に変換する糧の量を指定します。", 7, 5);
	container.createTextBox("ichiba_to_iron", "鉄に変換する糧の量","自動で鉄に変換する糧の量を指定します。", 7, 5);

	container.createTable();
	container.createCell();

	var villageSetting = Game.getVillageSetting(vId);
	container.setValue(villageSetting);

	container.createTable();
	container.createCell();

	container.createButton("saveFacility", "保存", "設定内容を保存します", function() {
		var villageSetting = container.getValue();
		Game.saveVillageSetting(vId, villageSetting);
	});
	container.createButton("closeFacility", "閉じる", "設定内容を保存せず閉じます", function() {closeInifacBox()});
	container.createButton("clearFacility", "ALLｸﾘｱ", "設定内容を消去します。", function() {clearInifacBox()});
}


//URLパラメータ取得
function getParameter(key) {
	var str = location.search.split("?");
	if (str.length < 2) {
		return "";
	}
	
	var params = str[1].split("&");
	for (var i = 0; i < params.length; i++) {
		var keyVal = params[i].split("=");
		if (keyVal[0] == key && keyVal.length == 2) {
			return decodeURIComponent(keyVal[1]);
		}
	}
	return "";
}

//先頭ゼロ付加
function padZero(num) {
	var result;
	if (num < 10) {
		result = "0" + num;
	} else {
		result = "" + num;
	}
	return result;
}
//先頭ゼロ除去
function trimZero(str) {
	var res = str.replace(/^0*/, "");
	if (res == "") res = "0";
	return res;
}

//空白除去
function trim(str) {
	if (str == undefined) return "";
	return str.replace(/^[ 　\t\r\n]+|[ 　\t\r\n]+$/g, "");
}

//数値チェック
function isNumeric(num) {
	if (num.match(/^-?[0-9]+$/)) {
		return true;
	}
	return false;
}

//子Element取得
function getChildElement(parentNode, position) {
	var current = 0;
	for (var i = 0; i < parentNode.childNodes.length; i++){
		var childNode = parentNode.childNodes[i];
		if (childNode.nodeType == 1) {
			if (current == position) {
				return childNode;
			}
			current++;
		}
	}
	
	return undefined;
}

//---------------------
//市場変換、自動内政系



//市場変換処理
function ichibaChange() {
	var gameSetting = Game.getGameSetting();
	var ichibaInfo = Game.getIchibaInfo();
	if (ichibaInfo.position != undefined && (gameSetting.ichiba.min1.enable || gameSetting.ichiba.max1.enable || gameSetting.ichiba.max2.enable)) {
		var resources = Game.getResources();
		var resourcesIncrese = Game.getResourcesIncrese();
		var resourceCapacity = Game.getResourceCapacity();
		var ichibaRate = Facility.ichiba[parseInt(ichibaInfo.lv, 10) - 1];
		if (gameSetting.ichiba.min1.enable) {
			var min1Rice = parseInt(gameSetting.ichiba.min1.rice, 10);
			var min1RiceLimit = parseInt(gameSetting.ichiba.min1.rice_limit, 10);
			var min1Wood = parseInt(gameSetting.ichiba.min1.wood, 10);
			var min1WoodLimit = parseInt(gameSetting.ichiba.min1.wood_limit, 10);
			var min1Stone = parseInt(gameSetting.ichiba.min1.stone, 10);
			var min1StoneLimit = parseInt(gameSetting.ichiba.min1.stone_limit, 10);
			var min1Iron = parseInt(gameSetting.ichiba.min1.iron, 10);
			var min1IronLimit = parseInt(gameSetting.ichiba.min1.iron_limit, 10);
			if (resources.rice > min1Rice) {
				var deficiencies = {};
				deficiencies.wood = resources.wood < min1Wood? min1Wood - resources.wood: 0;
				deficiencies.stone = resources.stone < min1Stone? min1Stone - resources.stone: 0;
				deficiencies.iron = resources.iron < min1Iron? min1Iron - resources.iron: 0;
				if (deficiencies.wood + deficiencies.stone + deficiencies.iron > 20) {
					if (ichibaInfo.position == Game.getCurrentVillagePosition()) {
						var convertRate = (resources.rice - min1RiceLimit) * ichibaRate / (deficiencies.wood + deficiencies.stone + deficiencies.iron);
						if (convertRate > 1) convertRate = 1;
						var village = Game.getCurrentVillage();
						var actions = [];
						if (deficiencies.wood * convertRate > 20) {
							GM_log('wood' + (Math.floor(deficiencies.wood * convertRate / ichibaRate / 10) * 10));
							actions.push({from: 104, amount: Math.floor(deficiencies.wood * convertRate / ichibaRate / 10) * 10, to: 101});
						}
						if (deficiencies.stone * convertRate > 20) {
							GM_log('stone' + (Math.floor(deficiencies.stone * convertRate / ichibaRate / 10) * 10));
							actions.push({from: 104, amount: Math.floor(deficiencies.stone * convertRate / ichibaRate / 10) * 10, to: 102});
						}
						if (deficiencies.iron * convertRate > 20) {
							GM_log('iron' + (Math.floor(deficiencies.iron * convertRate / ichibaRate / 10) * 10));
							actions.push({from: 104, amount: Math.floor(deficiencies.iron * convertRate / ichibaRate / 10) * 10, to: 103});
						}
						village.convertResources(actions);
						return true;
					} else {
						var villageInfo = Game.getVillageInfo(ichibaInfo.position);
						if (villageInfo != null) {
							Game.saveForceNextAction(Game.getCurrentVillagePosition());
							var tid = setTimeout(function() {location.href = villageInfo.url}, INTERVAL);
							return true;
						}
					}
				}
			}
		}
		if (gameSetting.ichiba.max1.enable) {
			var max1maxHours = parseInt(gameSetting.ichiba.max1.maxHours, 10);
			var max1minHours = parseInt(gameSetting.ichiba.max1.minHours, 10);
			var convertRate = {
				wood: parseInt(gameSetting.ichiba.max1.convertRate.wood, 10),
				stone: parseInt(gameSetting.ichiba.max1.convertRate.stone, 10),
				iron: parseInt(gameSetting.ichiba.max1.convertRate.iron, 10)
			};
			if (resources.rice > resourceCapacity - resourcesIncrese.rice * max1maxHours) {
				var convertTo = {wood: 0, stone: 0, iron: 0};
				var convertFrom = 0;
				var targetTo = ['wood', 'stone', 'iron'];
				var changeHour = max1minHours - max1maxHours;
				var riceFullTime = (resourceCapacity - resources.rice + convertFrom) / resourcesIncrese.rice;
				while (riceFullTime < max1minHours && targetTo.length > 0) {
					var remainTarget = [];
					var sumConvertRate = 0;
					for (var i = 0, l = targetTo.length; i < l; ++i) {
						sumConvertRate += convertRate[targetTo[i]];
					}
					var changeToAmount = Math.floor(resourcesIncrese.rice * changeHour * ichibaRate / sumConvertRate);
					var changeFromAmount = Math.floor(resourcesIncrese.rice * changeHour / sumConvertRate);
					for (var i = 0, l = targetTo.length; i < l; ++i) {
						if ((resourceCapacity - resources[targetTo[i]] - convertTo[targetTo[i]] - changeToAmount * convertRate[targetTo[i]]) / resourcesIncrese[targetTo[i]] > riceFullTime) {
							convertFrom += changeFromAmount * convertRate[targetTo[i]];
							convertTo[targetTo[i]] += changeToAmount * convertRate[targetTo[i]];
							remainTarget.push(targetTo[i]);
						}
					}
					targetTo = remainTarget;
					riceFullTime = (resourceCapacity - resources.rice + convertFrom) / resourcesIncrese.rice;
				}
				if (convertFrom > 20) {
					if (ichibaInfo.position == Game.getCurrentVillagePosition()) {
						var village = Game.getCurrentVillage();
						var actions = [];
						if (convertTo.wood > 20) {
							GM_log('wood' + (Math.floor(convertTo.wood / ichibaRate / 10) * 10));
							actions.push({from: 104, amount: Math.floor(convertTo.wood / ichibaRate / 10) * 10, to: 101});
						}
						if (convertTo.stone > 20) {
							GM_log('stone' + (Math.floor(convertTo.stone / ichibaRate / 10) * 10));
							actions.push({from: 104, amount: Math.floor(convertTo.stone / ichibaRate / 10) * 10, to: 102});
						}
						if (convertTo.iron > 20) {
							GM_log('iron' + (Math.floor(convertTo.iron / ichibaRate / 10) * 10));
							actions.push({from: 104, amount: Math.floor(convertTo.iron / ichibaRate / 10) * 10, to: 103});
						}
						village.convertResources(actions);
						return true;
					} else {
						var villageInfo = Game.getVillageInfo(ichibaInfo.position);
						if (villageInfo != null) {
							Game.saveForceNextAction(Game.getCurrentVillagePosition());
							var tid = setTimeout(function() {location.href = villageInfo.url}, INTERVAL);
							return true;
						}
					}
				}
			}
		}
		if (gameSetting.ichiba.max2.enable) {
			var maxRice = parseInt(gameSetting.ichiba.max2.maxRice, 10);
			var convertAmount = {
				wood: parseInt(gameSetting.ichiba.max2.convertAmount.wood, 10),
				stone: parseInt(gameSetting.ichiba.max2.convertAmount.stone, 10),
				iron: parseInt(gameSetting.ichiba.max2.convertAmount.iron, 10)
			};
			var maxAmount = {
				wood: parseInt(gameSetting.ichiba.max2.maxAmount.wood, 10),
				stone: parseInt(gameSetting.ichiba.max2.maxAmount.stone, 10),
				iron: parseInt(gameSetting.ichiba.max2.maxAmount.iron, 10)
			};
			if (resources.rice > maxRice) {
				var convertTo = {wood: 0, stone: 0, iron: 0};
				var convertFrom = 0;
				var targetTo = ['wood', 'stone', 'iron'];
				for (var i = 0, l = targetTo.length; i < l; ++i) {
					if (maxAmount[targetTo[i]] > resources[targetTo[i]]) {
						if (maxAmount[targetTo[i]] > resources[targetTo[i]] + convertAmount[targetTo[i]] * ichibaRate) {
							convertTo[targetTo[i]] = convertAmount[targetTo[i]];
						} else {
							convertTo[targetTo[i]] = (maxAmount[targetTo[i]] - resources[targetTo[i]]) / ichibaRate;
						}
						convertFrom += convertTo[targetTo[i]];
					}
				}
				if (convertFrom > 20) {
					if (ichibaInfo.position == Game.getCurrentVillagePosition()) {
						var village = Game.getCurrentVillage();
						var actions = [];
						if (convertTo.wood > 20) {
							GM_log('wood' + convertTo.wood);
							actions.push({from: 104, amount: convertTo.wood, to: 101});
						}
						if (convertTo.stone > 20) {
							GM_log('stone' + convertTo.stone);
							actions.push({from: 104, amount: convertTo.stone, to: 102});
						}
						if (convertTo.iron > 20) {
							GM_log('iron' + convertTo.iron);
							actions.push({from: 104, amount: convertTo.iron, to: 103});
						}
						village.convertResources(actions);
						return true;
					} else {
						var villageInfo = Game.getVillageInfo(ichibaInfo.position);
						if (villageInfo != null) {
							Game.saveForceNextAction(Game.getCurrentVillagePosition());
							var tid = setTimeout(function() {location.href = villageInfo.url}, INTERVAL);
							return true;
						}
					}
				}
			}
		}
	}

	var villageSetting = Game.getVillageSetting();
	if(villageSetting.ichiba) {//old版
		//alert("市場自動変換未指定");

		var village = Game.getCurrentVillage();
		var ichiba = village.getMaxLevelFacility("市場");

		if(ichiba == null) {
			alert("市場がありません");
			return;
		}

		var RES_NOW = [];
		RES_NOW["wood"] = parseInt( $("wood").innerHTML, 10 );
		RES_NOW["stone"] = parseInt( $("stone").innerHTML, 10 );
		RES_NOW["iron"] = parseInt( $("iron").innerHTML, 10 );
		RES_NOW["rice"] = parseInt( $("rice").innerHTML, 10 );
		
		var ichibaRiceMax = parseInt(villageSetting.ichiba_rice_max, 10);
		var ichibaToWood = parseInt(villageSetting.ichiba_to_wood, 10);
		var ichibaToStone = parseInt(villageSetting.ichiba_to_stone, 10);
		var ichibaToIron = parseInt(villageSetting.ichiba_to_iron, 10);

		//糧が指定量より多いかチェック
		if(RES_NOW["rice"] < ichibaRiceMax) {
			//alert("糧が" + OPT_RISE_MAX + "未満");
			return;
		}
		
		if(villageSetting.ichiba_pa == 0){
			var min_sigen = RES_NOW["wood"];

			if(RES_NOW["stone"] < min_sigen ) { min_sigen = RES_NOW["stone"]; }
			if(RES_NOW["iron"] < min_sigen ) { min_sigen = RES_NOW["iron"]; }

			//糧から他の資源に返還開始
			if((ichibaToWood > 0) && ( RES_NOW["wood"] == min_sigen )) {
				changeResorceToResorce(RICE, ichibaToWood, WOOD, ichiba.x, ichiba.y);
			} else if((ichibaToStone > 0) && ( RES_NOW["stone"] == min_sigen )) {
				changeResorceToResorce(RICE, ichibaToStone, STONE, ichiba.x, ichiba.y);
			} else if((ichibaToIron > 0) && ( RES_NOW["iron"] == min_sigen )) {
				changeResorceToResorce(RICE, ichibaToIron, IRON, ichiba.x, ichiba.y);
			}
			return;
		}else{

			if(ichibaRiceMax < ichibaToWood + ichibaToStone + ichibaToIron){
				alert("変換する総合計より糧の値を大きくしてください。");
			}else{
				changeResorceToResorce(RICE, ichibaToWood, WOOD, ichiba.x, ichiba.y);
				changeResorceToResorce(RICE, ichibaToStone, STONE, ichiba.x, ichiba.y);
				changeResorceToResorce(RICE, ichibaToIron, IRON, ichiba.x, ichiba.y);
			}
			return;
		}
	}
}

//実変換処理通信部
function changeResorceToResorce(from, tc, to, x, y) {
	var data = "form2=&x=" + x + "&y=" + y + "&change_btn=" + encodeURIComponent("はい") + "&st=1&tf_id=" + from + "&tc=" + tc + "&tt_id=" + to;
	var tid=setTimeout(function(){
		console.log("http://" + HOST + "/facility/facility.php");
		GM_xmlhttpRequest({
			method:"POST", 
			url:"http://" + HOST + "/facility/facility.php",
			headers:{"Content-type":"application/x-www-form-urlencoded"},
			data: data,
			onload:function(x){
				//console.log(x.responseText);
			}
		});
	},INTERVAL);
}

//自動寄付処理
function autoDonate() {
	var gameSetting = Game.getGameSetting();
	if(!gameSetting.kifu.enable) {
		//alert("自動寄付未指定");
		return;
	}

	//糧が指定量より多いかチェック
	if(parseInt($("rice").innerHTML, 10) < parseInt(gameSetting.kifu.rice_max, 10)) {
		//alert("糧が" + OPT_RISE_KIFU_MAX + "未満");
		return;
	}


	sendDonate(parseInt(gameSetting.kifu.rice, 10));
//	var tid=setTimeout(function(){location.reload();},INTERVAL);
}

//寄付処理通信部
function sendDonate(rice) {
	var data = "contributionForm=&wood=0&stone=0&iron=0&rice=" + rice + "&contribution=1";
	var tid=setTimeout(function(){
		GM_xmlhttpRequest({
			method:"POST", 
			url:"http://" + HOST + "/alliance/level.php",
			headers:{"Content-type":"application/x-www-form-urlencoded"},
			data: data,
			onload:function(x){console.log(x.responseText);}
		});
	},INTERVAL);
}
//内政スキルの使用
function Auto_Domestic() {
	var villageSetting = Game.getVillageSetting();
	if (!villageSetting.dome) {return;} //設定してなければ戻る
	
	var village = Game.getCurrentVillage();
	if (village.isSettingDomesticPerson() && !village.isUseDomesticSkill()) {
		var tid=setTimeout(function(){
			GM_xmlhttpRequest({
				method:"GET", 
				url:"http://" + HOST + "/card/domestic_setting.php",
				headers:{"Content-type":"text/html"},
				overrideMimeType:'text/html; charset=utf-8',
				onload:function(x){
					var htmldoc = document.createElement("html");
						htmldoc.innerHTML = x.responseText;
						
						var skillElems = document.evaluate('//*[@class="skill"]/a',htmldoc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
					if(skillElems.snapshotLength < 1){return;}
					
					//alert(skillTag);
					for(i=0;i<skillElems.snapshotLength;i++){
						var skillElem = skillElems.snapshotItem(i);
						var skillText = skillElem.textContent;
						if((skillText.indexOf("知識",0) > 1 )||(skillText.indexOf("技術",0) > 1 )||(skillText.indexOf("呉の治世",0) > 0 )||(skillText.indexOf("王佐",0) > 0 ) ){
							GM_log(skillElem.href);
							GM_xmlhttpRequest({
									method:"GET", 
									url:skillElem.href,
									headers:{"Content-type":"text/html"},
									overrideMimeType:'text/html; charset=utf-8',
									onload:function(x){
										//alert(x.responseText);
									}
							});
							break;
						}
					}
				}
			});
		},INTERVAL);
	}
}


